######## snakemake preamble start (automatically inserted, do not edit) ########
import sys; sys.path.extend(['/home/ckikawa/.conda/envs/seqneut-pipeline/lib/python3.11/site-packages', '/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/seqneut-pipeline', '/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024', '/home/ckikawa/.conda/envs/seqneut-pipeline/bin', '/home/ckikawa/.conda/envs/seqneut-pipeline/lib/python3.11', '/home/ckikawa/.conda/envs/seqneut-pipeline/lib/python3.11/lib-dynload', '/home/ckikawa/.local/lib/python3.11/site-packages', '/home/ckikawa/.conda/envs/seqneut-pipeline/lib/python3.11/site-packages', '/home/ckikawa/.cache/snakemake/snakemake/source-cache/runtime-cache/tmpy6xj203u/file/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/seqneut-pipeline/notebooks', '/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/seqneut-pipeline/notebooks']); import pickle; snakemake = pickle.loads(b'\x80\x04\x95\x9b\x83\x00\x00\x00\x00\x00\x00\x8c\x10snakemake.script\x94\x8c\tSnakemake\x94\x93\x94)\x81\x94}\x94(\x8c\x05input\x94\x8c\x0csnakemake.io\x94\x8c\nInputFiles\x94\x93\x94)\x81\x94(\x8c7results/barcode_counts/plate7_A230212d0_rd512_100.0.csv\x94\x8c7results/barcode_counts/plate7_A230212d0_rd512_150.0.csv\x94\x8c7results/barcode_counts/plate7_A230212d0_rd512_225.0.csv\x94\x8c7results/barcode_counts/plate7_A230212d0_rd512_337.5.csv\x94\x8c8results/barcode_counts/plate7_A230212d0_rd512_506.25.csv\x94\x8c9results/barcode_counts/plate7_A230212d0_rd512_759.375.csv\x94\x8c;results/barcode_counts/plate7_A230212d0_rd512_1139.0625.csv\x94\x8c<results/barcode_counts/plate7_A230212d0_rd512_1708.59375.csv\x94\x8c=results/barcode_counts/plate7_A230212d0_rd512_2562.890625.csv\x94\x8c=results/barcode_counts/plate7_A230212d0_rd512_3844.335938.csv\x94\x8c=results/barcode_counts/plate7_A230212d0_rd512_5766.503906.csv\x94\x8c(results/barcode_counts/plate7_none-1.csv\x94\x8c8results/barcode_counts/plate7_A230212d28_rd512_100.0.csv\x94\x8c8results/barcode_counts/plate7_A230212d28_rd512_150.0.csv\x94\x8c8results/barcode_counts/plate7_A230212d28_rd512_225.0.csv\x94\x8c8results/barcode_counts/plate7_A230212d28_rd512_337.5.csv\x94\x8c9results/barcode_counts/plate7_A230212d28_rd512_506.25.csv\x94\x8c:results/barcode_counts/plate7_A230212d28_rd512_759.375.csv\x94\x8c<results/barcode_counts/plate7_A230212d28_rd512_1139.0625.csv\x94\x8c=results/barcode_counts/plate7_A230212d28_rd512_1708.59375.csv\x94\x8c>results/barcode_counts/plate7_A230212d28_rd512_2562.890625.csv\x94\x8c>results/barcode_counts/plate7_A230212d28_rd512_3844.335938.csv\x94\x8c>results/barcode_counts/plate7_A230212d28_rd512_5766.503906.csv\x94\x8c(results/barcode_counts/plate7_none-2.csv\x94\x8c6results/barcode_fates/plate7_A230212d0_rd512_100.0.csv\x94\x8c6results/barcode_fates/plate7_A230212d0_rd512_150.0.csv\x94\x8c6results/barcode_fates/plate7_A230212d0_rd512_225.0.csv\x94\x8c6results/barcode_fates/plate7_A230212d0_rd512_337.5.csv\x94\x8c7results/barcode_fates/plate7_A230212d0_rd512_506.25.csv\x94\x8c8results/barcode_fates/plate7_A230212d0_rd512_759.375.csv\x94\x8c:results/barcode_fates/plate7_A230212d0_rd512_1139.0625.csv\x94\x8c;results/barcode_fates/plate7_A230212d0_rd512_1708.59375.csv\x94\x8c<results/barcode_fates/plate7_A230212d0_rd512_2562.890625.csv\x94\x8c<results/barcode_fates/plate7_A230212d0_rd512_3844.335938.csv\x94\x8c<results/barcode_fates/plate7_A230212d0_rd512_5766.503906.csv\x94\x8c\'results/barcode_fates/plate7_none-1.csv\x94\x8c7results/barcode_fates/plate7_A230212d28_rd512_100.0.csv\x94\x8c7results/barcode_fates/plate7_A230212d28_rd512_150.0.csv\x94\x8c7results/barcode_fates/plate7_A230212d28_rd512_225.0.csv\x94\x8c7results/barcode_fates/plate7_A230212d28_rd512_337.5.csv\x94\x8c8results/barcode_fates/plate7_A230212d28_rd512_506.25.csv\x94\x8c9results/barcode_fates/plate7_A230212d28_rd512_759.375.csv\x94\x8c;results/barcode_fates/plate7_A230212d28_rd512_1139.0625.csv\x94\x8c<results/barcode_fates/plate7_A230212d28_rd512_1708.59375.csv\x94\x8c=results/barcode_fates/plate7_A230212d28_rd512_2562.890625.csv\x94\x8c=results/barcode_fates/plate7_A230212d28_rd512_3844.335938.csv\x94\x8c=results/barcode_fates/plate7_A230212d28_rd512_5766.503906.csv\x94\x8c\'results/barcode_fates/plate7_none-2.csv\x94\x8c)data/viral_libraries/2023_H3N2_Kikawa.csv\x94\x8c3data/neut_standard_sets/loes2023_neut_standards.csv\x94e}\x94(\x8c\x06_names\x94}\x94(\x8c\ncount_csvs\x94K\x00K\x18\x86\x94\x8c\tfate_csvs\x94K\x18K0\x86\x94\x8c\x11viral_library_csv\x94K0N\x86\x94\x8c\x15neut_standard_set_csv\x94K1N\x86\x94u\x8c\x12_allowed_overrides\x94]\x94(\x8c\x05index\x94\x8c\x04sort\x94ehI\x8c\tfunctools\x94\x8c\x07partial\x94\x93\x94h\x06\x8c\x19Namedlist._used_attribute\x94\x93\x94\x85\x94R\x94(hO)}\x94\x8c\x05_name\x94hIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bh?h\x06\x8c\tNamedlist\x94\x93\x94)\x81\x94(h\nh\x0bh\x0ch\rh\x0eh\x0fh\x10h\x11h\x12h\x13h\x14h\x15h\x16h\x17h\x18h\x19h\x1ah\x1bh\x1ch\x1dh\x1eh\x1fh h!e}\x94(h=}\x94hG]\x94(hIhJehIhMhO\x85\x94R\x94(hO)}\x94hShIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bubhAhZ)\x81\x94(h"h#h$h%h&h\'h(h)h*h+h,h-h.h/h0h1h2h3h4h5h6h7h8h9e}\x94(h=}\x94hG]\x94(hIhJehIhMhO\x85\x94R\x94(hO)}\x94hShIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bubhCh:hEh;ub\x8c\x06output\x94h\x06\x8c\x0bOutputFiles\x94\x93\x94)\x81\x94(\x8c"results/plates/plate7/qc_drops.yml\x94\x8c*results/plates/plate7/frac_infectivity.csv\x94\x8c#results/plates/plate7/curvefits.csv\x94\x8c&results/plates/plate7/curvefits.pickle\x94e}\x94(h=}\x94(\x8c\x08qc_drops\x94K\x00N\x86\x94\x8c\x14frac_infectivity_csv\x94K\x01N\x86\x94\x8c\x08fits_csv\x94K\x02N\x86\x94\x8c\x0bfits_pickle\x94K\x03N\x86\x94uhG]\x94(hIhJehIhMhO\x85\x94R\x94(hO)}\x94hShIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bh}hwh\x7fhxh\x81hyh\x83hzub\x8c\x06params\x94h\x06\x8c\x06Params\x94\x93\x94)\x81\x94(]\x94(\x8c\x1cplate7_A230212d0_rd512_100.0\x94\x8c\x1cplate7_A230212d0_rd512_150.0\x94\x8c\x1cplate7_A230212d0_rd512_225.0\x94\x8c\x1cplate7_A230212d0_rd512_337.5\x94\x8c\x1dplate7_A230212d0_rd512_506.25\x94\x8c\x1eplate7_A230212d0_rd512_759.375\x94\x8c plate7_A230212d0_rd512_1139.0625\x94\x8c!plate7_A230212d0_rd512_1708.59375\x94\x8c"plate7_A230212d0_rd512_2562.890625\x94\x8c"plate7_A230212d0_rd512_3844.335938\x94\x8c"plate7_A230212d0_rd512_5766.503906\x94\x8c\rplate7_none-1\x94\x8c\x1dplate7_A230212d28_rd512_100.0\x94\x8c\x1dplate7_A230212d28_rd512_150.0\x94\x8c\x1dplate7_A230212d28_rd512_225.0\x94\x8c\x1dplate7_A230212d28_rd512_337.5\x94\x8c\x1eplate7_A230212d28_rd512_506.25\x94\x8c\x1fplate7_A230212d28_rd512_759.375\x94\x8c!plate7_A230212d28_rd512_1139.0625\x94\x8c"plate7_A230212d28_rd512_1708.59375\x94\x8c#plate7_A230212d28_rd512_2562.890625\x94\x8c#plate7_A230212d28_rd512_3844.335938\x94\x8c#plate7_A230212d28_rd512_5766.503906\x94\x8c\rplate7_none-2\x94e}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94\x8c\n2024-02-07\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-02-07_plate_mapping_file6.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(\x8c\x1bavg_barcode_counts_per_well\x94M\xf4\x01\x8c\x1fmin_neut_standard_frac_per_well\x94G?tz\xe1G\xae\x14{\x8c"no_serum_per_viral_barcode_filters\x94}\x94(\x8c\x08min_frac\x94G?\x1a6\xe2\xeb\x1cC-\x8c\x0fmax_fold_change\x94K\x04\x8c\tmax_wells\x94K\x02u\x8c!per_neut_standard_barcode_filters\x94}\x94(\x8c\x08min_frac\x94G?tz\xe1G\xae\x14{\x8c\x0fmax_fold_change\x94K\x04\x8c\tmax_wells\x94K\x02u\x8c min_neut_standard_count_per_well\x94M\xe8\x03\x8c)min_no_serum_count_per_viral_barcode_well\x94Kd\x8c+max_frac_infectivity_per_viral_barcode_well\x94K\x03\x8c)min_dilutions_per_barcode_serum_replicate\x94K\x06u\x8c\x0fcurvefit_params\x94}\x94(\x8c\x18frac_infectivity_ceiling\x94K\x01\x8c\x06fixtop\x94]\x94(G?\xe3333333K\x01e\x8c\tfixbottom\x94K\x00\x8c\x08fixslope\x94]\x94(G?\xe9\x99\x99\x99\x99\x99\x9aK\neu\x8c\x0bcurvefit_qc\x94}\x94(\x8c\x1dmax_frac_infectivity_at_least\x94G\x00\x00\x00\x00\x00\x00\x00\x00\x8c\x0fgoodness_of_fit\x94}\x94(\x8c\x06min_R2\x94G?\xe0\x00\x00\x00\x00\x00\x00\x8c\x08max_RMSD\x94G?\xc3333333u\x8c#serum_replicates_ignore_curvefit_qc\x94]\x94\x8c+barcode_serum_replicates_ignore_curvefit_qc\x94]\x94u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\x08upstream\x94\x8c\x1cCCTACAATGTCGGATTTGTATTTAATAG\x94\x8c\ndownstream\x94\x8c\x00\x94\x8c\x04minq\x94K\x14\x8c\x11upstream_mismatch\x94K\x04\x8c\x0ebc_orientation\x94\x8c\x02R2\x94u\x8c\x07samples\x94}\x94(\x8c\x04well\x94}\x94(K\x00\x8c\x02D1\x94K\x01\x8c\x02D2\x94K\x02\x8c\x02D3\x94K\x03\x8c\x02D4\x94K\x04\x8c\x02D5\x94K\x05\x8c\x02D6\x94K\x06\x8c\x02D7\x94K\x07\x8c\x02D8\x94K\x08\x8c\x02D9\x94K\t\x8c\x03D10\x94K\n\x8c\x03D11\x94K\x0b\x8c\x03D12\x94K\x0c\x8c\x02H1\x94K\r\x8c\x02H2\x94K\x0e\x8c\x02H3\x94K\x0f\x8c\x02H4\x94K\x10\x8c\x02H5\x94K\x11\x8c\x02H6\x94K\x12\x8c\x02H7\x94K\x13\x8c\x02H8\x94K\x14\x8c\x02H9\x94K\x15\x8c\x03H10\x94K\x16\x8c\x03H11\x94K\x17\x8c\x03H12\x94u\x8c\x05serum\x94}\x94(K\x00\x8c\x0fA230212d0_rd512\x94K\x01j\x05\x01\x00\x00K\x02j\x05\x01\x00\x00K\x03j\x05\x01\x00\x00K\x04j\x05\x01\x00\x00K\x05j\x05\x01\x00\x00K\x06j\x05\x01\x00\x00K\x07j\x05\x01\x00\x00K\x08j\x05\x01\x00\x00K\tj\x05\x01\x00\x00K\nj\x05\x01\x00\x00K\x0b\x8c\x04none\x94K\x0c\x8c\x10A230212d28_rd512\x94K\rj\x07\x01\x00\x00K\x0ej\x07\x01\x00\x00K\x0fj\x07\x01\x00\x00K\x10j\x07\x01\x00\x00K\x11j\x07\x01\x00\x00K\x12j\x07\x01\x00\x00K\x13j\x07\x01\x00\x00K\x14j\x07\x01\x00\x00K\x15j\x07\x01\x00\x00K\x16j\x07\x01\x00\x00K\x17j\x06\x01\x00\x00u\x8c\x0fdilution_factor\x94}\x94(K\x00G@Y\x00\x00\x00\x00\x00\x00K\x01G@b\xc0\x00\x00\x00\x00\x00K\x02G@l \x00\x00\x00\x00\x00K\x03G@u\x18\x00\x00\x00\x00\x00K\x04G@\x7f\xa4\x00\x00\x00\x00\x00K\x05G@\x87\xbb\x00\x00\x00\x00\x00K\x06G@\x91\xcc@\x00\x00\x00\x00K\x07G@\x9a\xb2`\x00\x00\x00\x00K\x08G@\xa4\x05\xc8\x00\x00\x00\x00K\tG@\xae\x08\xac\x00\x10\xc6\xf8K\nG@\xb6\x86\x80\xff\xfb\xceBK\x0bG\x7f\xf8\x00\x00\x00\x00\x00\x00K\x0cG@Y\x00\x00\x00\x00\x00\x00K\rG@b\xc0\x00\x00\x00\x00\x00K\x0eG@l \x00\x00\x00\x00\x00K\x0fG@u\x18\x00\x00\x00\x00\x00K\x10G@\x7f\xa4\x00\x00\x00\x00\x00K\x11G@\x87\xbb\x00\x00\x00\x00\x00K\x12G@\x91\xcc@\x00\x00\x00\x00K\x13G@\x9a\xb2`\x00\x00\x00\x00K\x14G@\xa4\x05\xc8\x00\x00\x00\x00K\x15G@\xae\x08\xac\x00\x10\xc6\xf8K\x16G@\xb6\x86\x80\xff\xfb\xceBK\x17G\x7f\xf8\x00\x00\x00\x00\x00\x00u\x8c\treplicate\x94}\x94(K\x00K\x01K\x01K\x01K\x02K\x01K\x03K\x01K\x04K\x01K\x05K\x01K\x06K\x01K\x07K\x01K\x08K\x01K\tK\x01K\nK\x01K\x0bK\x01K\x0cK\x01K\rK\x01K\x0eK\x01K\x0fK\x01K\x10K\x01K\x11K\x01K\x12K\x01K\x13K\x01K\x14K\x01K\x15K\x01K\x16K\x01K\x17K\x02u\x8c\x05fastq\x94}\x94(K\x00\x8c\x8d/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc1_S4_R1_001.fastq.gz\x94K\x01\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc2_S12_R1_001.fastq.gz\x94K\x02\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc3_S20_R1_001.fastq.gz\x94K\x03\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc4_S28_R1_001.fastq.gz\x94K\x04\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc5_S36_R1_001.fastq.gz\x94K\x05\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc6_S44_R1_001.fastq.gz\x94K\x06\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc7_S52_R1_001.fastq.gz\x94K\x07\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc8_S60_R1_001.fastq.gz\x94K\x08\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc9_S68_R1_001.fastq.gz\x94K\t\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc10_S76_R1_001.fastq.gz\x94K\n\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_conc11_S84_R1_001.fastq.gz\x94K\x0b\x8c\x90/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d0_noSerum_S92_R1_001.fastq.gz\x94K\x0c\x8c\x8e/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc1_S8_R1_001.fastq.gz\x94K\r\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc2_S16_R1_001.fastq.gz\x94K\x0e\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc3_S24_R1_001.fastq.gz\x94K\x0f\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc4_S32_R1_001.fastq.gz\x94K\x10\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc5_S40_R1_001.fastq.gz\x94K\x11\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc6_S48_R1_001.fastq.gz\x94K\x12\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc7_S56_R1_001.fastq.gz\x94K\x13\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc8_S64_R1_001.fastq.gz\x94K\x14\x8c\x8f/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc9_S72_R1_001.fastq.gz\x94K\x15\x8c\x90/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc10_S80_R1_001.fastq.gz\x94K\x16\x8c\x90/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_conc11_S88_R1_001.fastq.gz\x94K\x17\x8c\x91/fh/fast/bloom_j/SR/ngs/illumina/bloom_lab/240206_VH00699_434_AAFGTH5M5/Unaligned/Project_bloom_lab/rd512_A230212_d28_noSerum_S96_R1_001.fastq.gz\x94u\x8c\x0fserum_replicate\x94}\x94(K\x00j\x05\x01\x00\x00K\x01j\x05\x01\x00\x00K\x02j\x05\x01\x00\x00K\x03j\x05\x01\x00\x00K\x04j\x05\x01\x00\x00K\x05j\x05\x01\x00\x00K\x06j\x05\x01\x00\x00K\x07j\x05\x01\x00\x00K\x08j\x05\x01\x00\x00K\tj\x05\x01\x00\x00K\nj\x05\x01\x00\x00K\x0b\x8c\x06none-1\x94K\x0cj\x07\x01\x00\x00K\rj\x07\x01\x00\x00K\x0ej\x07\x01\x00\x00K\x0fj\x07\x01\x00\x00K\x10j\x07\x01\x00\x00K\x11j\x07\x01\x00\x00K\x12j\x07\x01\x00\x00K\x13j\x07\x01\x00\x00K\x14j\x07\x01\x00\x00K\x15j\x07\x01\x00\x00K\x16j\x07\x01\x00\x00K\x17\x8c\x06none-2\x94u\x8c\x0esample_noplate\x94}\x94(K\x00\x8c\x15A230212d0_rd512_100.0\x94K\x01\x8c\x15A230212d0_rd512_150.0\x94K\x02\x8c\x15A230212d0_rd512_225.0\x94K\x03\x8c\x15A230212d0_rd512_337.5\x94K\x04\x8c\x16A230212d0_rd512_506.25\x94K\x05\x8c\x17A230212d0_rd512_759.375\x94K\x06\x8c\x19A230212d0_rd512_1139.0625\x94K\x07\x8c\x1aA230212d0_rd512_1708.59375\x94K\x08\x8c\x1bA230212d0_rd512_2562.890625\x94K\t\x8c\x1bA230212d0_rd512_3844.335938\x94K\n\x8c\x1bA230212d0_rd512_5766.503906\x94K\x0bj(\x01\x00\x00K\x0c\x8c\x16A230212d28_rd512_100.0\x94K\r\x8c\x16A230212d28_rd512_150.0\x94K\x0e\x8c\x16A230212d28_rd512_225.0\x94K\x0f\x8c\x16A230212d28_rd512_337.5\x94K\x10\x8c\x17A230212d28_rd512_506.25\x94K\x11\x8c\x18A230212d28_rd512_759.375\x94K\x12\x8c\x1aA230212d28_rd512_1139.0625\x94K\x13\x8c\x1bA230212d28_rd512_1708.59375\x94K\x14\x8c\x1cA230212d28_rd512_2562.890625\x94K\x15\x8c\x1cA230212d28_rd512_3844.335938\x94K\x16\x8c\x1cA230212d28_rd512_5766.503906\x94K\x17j)\x01\x00\x00u\x8c\x06sample\x94}\x94(K\x00h\x93K\x01h\x94K\x02h\x95K\x03h\x96K\x04h\x97K\x05h\x98K\x06h\x99K\x07h\x9aK\x08h\x9bK\th\x9cK\nh\x9dK\x0bh\x9eK\x0ch\x9fK\rh\xa0K\x0eh\xa1K\x0fh\xa2K\x10h\xa3K\x11h\xa4K\x12h\xa5K\x13h\xa6K\x14h\xa7K\x15h\xa8K\x16h\xa9K\x17h\xaau\x8c\x05plate\x94}\x94(K\x00\x8c\x06plate7\x94K\x01jF\x01\x00\x00K\x02jF\x01\x00\x00K\x03jF\x01\x00\x00K\x04jF\x01\x00\x00K\x05jF\x01\x00\x00K\x06jF\x01\x00\x00K\x07jF\x01\x00\x00K\x08jF\x01\x00\x00K\tjF\x01\x00\x00K\njF\x01\x00\x00K\x0bjF\x01\x00\x00K\x0cjF\x01\x00\x00K\rjF\x01\x00\x00K\x0ejF\x01\x00\x00K\x0fjF\x01\x00\x00K\x10jF\x01\x00\x00K\x11jF\x01\x00\x00K\x12jF\x01\x00\x00K\x13jF\x01\x00\x00K\x14jF\x01\x00\x00K\x15jF\x01\x00\x00K\x16jF\x01\x00\x00K\x17jF\x01\x00\x00u\x8c\x0fplate_replicate\x94}\x94(K\x00jF\x01\x00\x00K\x01jF\x01\x00\x00K\x02jF\x01\x00\x00K\x03jF\x01\x00\x00K\x04jF\x01\x00\x00K\x05jF\x01\x00\x00K\x06jF\x01\x00\x00K\x07jF\x01\x00\x00K\x08jF\x01\x00\x00K\tjF\x01\x00\x00K\njF\x01\x00\x00K\x0b\x8c\x08plate7-1\x94K\x0cjF\x01\x00\x00K\rjF\x01\x00\x00K\x0ejF\x01\x00\x00K\x0fjF\x01\x00\x00K\x10jF\x01\x00\x00K\x11jF\x01\x00\x00K\x12jF\x01\x00\x00K\x13jF\x01\x00\x00K\x14jF\x01\x00\x00K\x15jF\x01\x00\x00K\x16jF\x01\x00\x00K\x17\x8c\x08plate7-2\x94uuue}\x94(h=}\x94(h\xe7K\x00N\x86\x94\x8c\x0cplate_params\x94K\x01N\x86\x94uhG]\x94(hIhJehIhMhO\x85\x94R\x94(hO)}\x94hShIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bh\xe7h\x92jN\x01\x00\x00h\xabub\x8c\twildcards\x94h\x06\x8c\tWildcards\x94\x93\x94)\x81\x94\x8c\x06plate7\x94a}\x94(h=}\x94\x8c\x05plate\x94K\x00N\x86\x94shG]\x94(hIhJehIhMhO\x85\x94R\x94(hO)}\x94hShIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bjD\x01\x00\x00j]\x01\x00\x00ub\x8c\x07threads\x94K\x01\x8c\tresources\x94h\x06\x8c\tResources\x94\x93\x94)\x81\x94(K\x01K\x01\x8c\x15/loc/scratch/64245082\x94e}\x94(h=}\x94(\x8c\x06_cores\x94K\x00N\x86\x94\x8c\x06_nodes\x94K\x01N\x86\x94\x8c\x06tmpdir\x94K\x02N\x86\x94uhG]\x94(hIhJehIhMhO\x85\x94R\x94(hO)}\x94hShIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bjs\x01\x00\x00K\x01ju\x01\x00\x00K\x01jw\x01\x00\x00jp\x01\x00\x00ub\x8c\x03log\x94h\x06\x8c\x03Log\x94\x93\x94)\x81\x94\x8c*results/plates/plate7/process_plate7.ipynb\x94a}\x94(h=}\x94\x8c\x08notebook\x94K\x00N\x86\x94shG]\x94(hIhJehIhMhO\x85\x94R\x94(hO)}\x94hShIsNt\x94bhJhMhO\x85\x94R\x94(hO)}\x94hShJsNt\x94bj\x89\x01\x00\x00j\x86\x01\x00\x00ub\x8c\x06config\x94}\x94(\x8c\x10seqneut-pipeline\x94\x8c\x10seqneut-pipeline\x94\x8c\x04docs\x94\x8c\x04docs\x94\x8c\x0bdescription\x94X\n\x01\x00\x00# Sequencing-based neutralization assays of 2023-2024 human serum samples versus H3N2 influenza libraries\n\nThe numerical data and computer code are at [https://github.com/jbloomlab/flu_seqneut_H3N2_2023-2024](https://github.com/jbloomlab/flu_seqneut_H3N2_2023-2024)\n\x94\x8c\x0fviral_libraries\x94}\x94(\x8c\x0cH3N2_library\x94\x8c)data/viral_libraries/2023_H3N2_Kikawa.csv\x94\x8c\x0cH1N1_library\x94\x8c-data/viral_libraries/pdmH1N1_lib2023_loes.csv\x94u\x8c\x17viral_strain_plot_order\x94\x8c)data/H3N2library_2023-2024_allStrains.csv\x94\x8c\x12neut_standard_sets\x94}\x94\x8c\x08loes2023\x94\x8c3data/neut_standard_sets/loes2023_neut_standards.csv\x94s\x8c\x1eillumina_barcode_parser_params\x94}\x94(h\xdfh\xe0h\xe1h\xe2h\xe3K\x14h\xe4K\x04h\xe5h\xe6u\x8c#default_process_plate_qc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c%default_process_plate_curvefit_params\x94}\x94(h\xccK\x01h\xcd]\x94(G?\xe3333333K\x01eh\xcfK\x00h\xd0]\x94(G?\xe9\x99\x99\x99\x99\x99\x9aK\neu\x8c!default_process_plate_curvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9]\x94h\xdb]\x94u\x8c\x16default_serum_titer_as\x94\x8c\x08midpoint\x94\x8c\x1bdefault_serum_qc_thresholds\x94}\x94(\x8c\x0emin_replicates\x94K\x02\x8c\x1bmax_fold_change_from_median\x94K\x06\x8c\x11viruses_ignore_qc\x94]\x94u\x8c\x16sera_override_defaults\x94}\x94\x8c\x06plates\x94}\x94(\x8c\x06plate1\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94\x8c\x08datetime\x94\x8c\x04date\x94\x93\x94C\x04\x07\xe8\x01\x19\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-01-22_plate_mapping_file2.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x06plate2\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x01\x19\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-01-22_plate_mapping_file1.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x06plate3\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x01\x19\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-01-22_plate_mapping_file3.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\x18barcode_serum_replicates\x94]\x94(]\x94(\x8c\x10AATGACAGCTGTCTAG\x94\x8c\x12A230212d0_r64_rep1\x94e]\x94(\x8c\x10ATAGAAAATTATCCGC\x94\x8c\x12A230212d0_r64_rep1\x94ees\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x06plate4\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x02\x07\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-02-07_plate_mapping_file7.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x06plate5\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x02\x07\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-02-07_plate_mapping_file4.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x06plate6\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x02\x07\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-02-07_plate_mapping_file5.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uujF\x01\x00\x00}\x94(h\xach\xadh\xaej\xca\x01\x00\x00C\x04\x07\xe8\x02\x07\x94\x85\x94R\x94h\xb0h\xb1h\xb2h\xb3h\xb4h\xb5h\xb6}\x94h\xb8}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06uh\xca}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00uh\xd2}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x0eplate8_r32_50k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-03-04_plate_mapping_file10.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x0eplate9_r64_50k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-03-04_plate_mapping_file12.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x10plate10_r128_50k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-03-04_plate_mapping_file8.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x0fplate11_r32_75k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-03-04_plate_mapping_file11.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x0fplate12_r64_75k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-03-04_plate_mapping_file13.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x10plate13_r128_75k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c.data/plates/2024-03-04_plate_mapping_file9.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x07plate14\x94}\x94(\x8c\x05group\x94\x8c\x0eplatesToRepeat\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x13\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-03-19_plate_mapping_file14.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rbarcode_wells\x94]\x94(]\x94(\x8c\x10AAGTATTGCTACACAT\x94\x8c\x02H3\x94e]\x94(\x8c\x10CCTATAAGGCCTTACG\x94\x8c\x02H3\x94ees\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x07plate15\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x1c\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-03-28_plate_mapping_file15.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x07plate16\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\t\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-09_plate_mapping_file16.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x07plate17\x94}\x94(\x8c\x05group\x94\x8c\x03SCH\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\x0b\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-11_plate_mapping_file17.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\x05wells\x94]\x94\x8c\x02A9\x94as\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x07plate18\x94}\x94(\x8c\x05group\x94\x8c\x03SCH\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\x0b\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-11_plate_mapping_file18.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x0cplate19_100k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\x10\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-23_plate_mapping_file21.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x0cplate20_150k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\x10\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-23_plate_mapping_file22.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x0cplate21_200k\x94}\x94(\x8c\x05group\x94\x8c\x05pilot\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\x10\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-23_plate_mapping_file23.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x07plate22\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\x12\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-18_plate_mapping_file19.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06TGACGC\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate23\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x04\x12\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-04-18_plate_mapping_file20.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06CAGTTG\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate24\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x02\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-02_plate_mapping_file24.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00uu\x8c\x07plate25\x94}\x94(\x8c\x05group\x94\x8c\x03SCH\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x14\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-20_plate_mapping_file27.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06TGACGC\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate26\x94}\x94(\x8c\x05group\x94\x8c\x03SCH\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x14\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-20_plate_mapping_file28.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06CAGTTG\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate27\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x11\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-17_plate_mapping_file26.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?PbM\xd2\xf1\xa9\xfch\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06GCTACA\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate28\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x11\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-17_plate_mapping_file25.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?PbM\xd2\xf1\xa9\xfch\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06ATCGAT\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate29\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x1c\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-28_plate_mapping_file30.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06TGACGC\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate30\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x1c\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-28_plate_mapping_file29.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06CAGTTG\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate31\x94}\x94(\x8c\x05group\x94\x8c\x03SCH\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x1e\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-30_plate_mapping_file31.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06GCTACA\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate32\x94}\x94(\x8c\x05group\x94\x8c\x03SCH\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x1e\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-05-30_plate_mapping_file32.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\x08barcodes\x94]\x94\x8c\x10CCAATCCCAGCCTTTA\x94as\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06ATCGAT\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate33\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x06\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-06-04_plate_mapping_file34.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06TGACGC\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate34\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x06\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-06-04_plate_mapping_file33.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06CAGTTG\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate35\x94}\x94(\x8c\x05group\x94\x8c\x11PennVaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x06\x04\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-07-02_plate_mapping_file36.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06ATCGAT\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate36\x94}\x94(\x8c\x05group\x94\x8c\x03SCH\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x05\x1e\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-07-02_plate_mapping_file35.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06TGACGC\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate37\x94}\x94(\x8c\x05group\x94\x8c\x11MA22VaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\t\x18\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-09-24_plate_mapping_file37.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06ATCGAT\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate38\x94}\x94(\x8c\x05group\x94\x8c\nPooledSera\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\t\x18\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-09-24_plate_mapping_file38.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06ATCGAT\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate39\x94}\x94(\x8c\x05group\x94\x8c\nPooledSera\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\t\x19\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-09-25_plate_mapping_file40.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06GCTACA\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate40\x94}\x94(\x8c\x05group\x94\x8c\x11MA22VaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\t\x19\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-09-25_plate_mapping_file41.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\x05wells\x94]\x94(\x8c\x03C10\x94\x8c\x03C11\x94es\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06GCTACA\x94\x8c\x12upstream2_mismatch\x94K\x01uu\x8c\x07plate41\x94}\x94(\x8c\x05group\x94\x8c\x11MA22VaccineCohort\x94\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\t\x19\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c/data/plates/2024-09-25_plate_mapping_file39.csv\x94\x8c\x0cmanual_drops\x94}\x94\x8c\rqc_thresholds\x94}\x94(h\xbaM\xf4\x01h\xbbG?tz\xe1G\xae\x14{h\xbc}\x94(h\xbeG?\x1a6\xe2\xeb\x1cC-h\xbfK\x04h\xc0K\x02uh\xc1}\x94(h\xc3G?tz\xe1G\xae\x14{h\xc4K\x04h\xc5K\x02uh\xc6M\xe8\x03h\xc7Kdh\xc8K\x03h\xc9K\x06u\x8c\x0fcurvefit_params\x94}\x94(h\xccK\x01h\xcdj\xb0\x01\x00\x00h\xcfK\x00h\xd0j\xb1\x01\x00\x00u\x8c\x0bcurvefit_qc\x94}\x94(h\xd4G\x00\x00\x00\x00\x00\x00\x00\x00h\xd5}\x94(h\xd7G?\xe0\x00\x00\x00\x00\x00\x00h\xd8G?\xc3333333uh\xd9j\xb5\x01\x00\x00h\xdbj\xb6\x01\x00\x00u\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06ATCGAT\x94\x8c\x12upstream2_mismatch\x94K\x01uuu\x8c\x14miscellaneous_plates\x94}\x94(\x8c\x13240111_initial_H3N2\x94}\x94(\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x01\x0b\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c=data/miscellaneous_plates/H3N2library_initialPool_samples.csv\x94u\x8c\x12240124_repool_H3N2\x94}\x94(\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x01\x18\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8cGdata/miscellaneous_plates/2024-01-22_H3N2_sampleData_rePool_MOItest.csv\x94u\x8c\x12240207_repool_H3N2\x94}\x94(\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x02\x07\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8cGdata/miscellaneous_plates/2024-02-07_H3N2_sampleData_rePool_MOItest.csv\x94u\x8c\x12240207_repool_H1N1\x94}\x94(\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x02\x07\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH1N1_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8cGdata/miscellaneous_plates/2024-02-07_H1N1_sampleData_rePool_MOItest.csv\x94u\x8c\x1f240328_repool_H3N2_variableCell\x94}\x94(\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\x03\x1c\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8cBdata/miscellaneous_plates/2024-03-28_H3N2_MOItest_variableCell.csv\x94u\x8c\x1c240924_repool_H3N2_balancing\x94}\x94(\x8c\x04date\x94j\xca\x01\x00\x00C\x04\x07\xe8\t\x18\x94\x85\x94R\x94\x8c\rviral_library\x94\x8c\x0cH3N2_library\x94\x8c\x11neut_standard_set\x94\x8c\x08loes2023\x94\x8c\x0bsamples_csv\x94\x8c>data/miscellaneous_plates/2024-09-24_repool_H3N2_balancing.csv\x94\x8c\x1eillumina_barcode_parser_params\x94}\x94(\x8c\tupstream2\x94\x8c\x06GCTACA\x94\x8c\x12upstream2_mismatch\x94K\x01uuuu\x8c\x04rule\x94\x8c\rprocess_plate\x94\x8c\x0fbench_iteration\x94N\x8c\tscriptdir\x94\x8ck/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/seqneut-pipeline/notebooks\x94ub.'); from snakemake.logging import logger; logger.printshellcmds = False; import os; os.chdir(r'/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024');
######## snakemake preamble end #########
Process plate counts to get fraction infectivities and fit curves¶
This notebook is designed to be run using snakemake, and analyzes a plate of sequencing-based neutralization assays.
The plots generated by this notebook are interactive, so you can mouseover points for details, use the mouse-scroll to zoom and pan, and use interactive dropdowns at the bottom of the plots.
Setup¶
Import Python modules:
import pickle
import sys
import altair as alt
import matplotlib.pyplot as plt
import neutcurve
import numpy
import pandas as pd
import ruamel.yaml as yaml
_ = alt.data_transformers.disable_max_rows()
Get the variables passed by snakemake:
count_csvs = snakemake.input.count_csvs
fate_csvs = snakemake.input.fate_csvs
viral_library_csv = snakemake.input.viral_library_csv
neut_standard_set_csv = snakemake.input.neut_standard_set_csv
qc_drops_yaml = snakemake.output.qc_drops
frac_infectivity_csv = snakemake.output.frac_infectivity_csv
fits_csv = snakemake.output.fits_csv
fits_pickle = snakemake.output.fits_pickle
samples = snakemake.params.samples
plate = snakemake.wildcards.plate
plate_params = snakemake.params.plate_params
# get thresholds turning lists into tuples as needed
manual_drops = {
filter_type: [tuple(w) if isinstance(w, list) else w for w in filter_drops]
for (filter_type, filter_drops) in plate_params["manual_drops"].items()
}
group = plate_params["group"]
qc_thresholds = plate_params["qc_thresholds"]
curvefit_params = plate_params["curvefit_params"]
curvefit_qc = plate_params["curvefit_qc"]
curvefit_qc["barcode_serum_replicates_ignore_curvefit_qc"] = [
tuple(w) for w in curvefit_qc["barcode_serum_replicates_ignore_curvefit_qc"]
]
print(f"Processing {plate=}")
samples_df = pd.DataFrame(plate_params["samples"])
print(f"\nPlate has {len(samples)} samples (wells)")
assert all(
(len(samples_df) == samples_df[c].nunique())
for c in ["well", "sample", "sample_noplate"]
)
assert len(samples_df) == len(
samples_df.groupby(["serum_replicate", "dilution_factor"])
)
assert len(samples) == len(count_csvs) == len(fate_csvs) == len(samples_df)
for d, key, title in [
(manual_drops, "manual_drops", "Data manually specified to drop:"),
(qc_thresholds, "qc_thresholds", "QC thresholds applied to data:"),
(curvefit_params, "curvefit_params", "Curve-fitting parameters:"),
(curvefit_qc, "curvefit_qc", "Curve-fitting QC:"),
]:
print(f"\n{title}")
yaml.YAML(typ="rt").dump({key: d}, stream=sys.stdout)
Processing plate='plate7'
Plate has 24 samples (wells)
Data manually specified to drop:
manual_drops: {}
QC thresholds applied to data:
qc_thresholds:
avg_barcode_counts_per_well: 500
min_neut_standard_frac_per_well: 0.005
no_serum_per_viral_barcode_filters:
min_frac: 0.0001
max_fold_change: 4
max_wells: 2
per_neut_standard_barcode_filters:
min_frac: 0.005
max_fold_change: 4
max_wells: 2
min_neut_standard_count_per_well: 1000
min_no_serum_count_per_viral_barcode_well: 100
max_frac_infectivity_per_viral_barcode_well: 3
min_dilutions_per_barcode_serum_replicate: 6
Curve-fitting parameters: curvefit_params: frac_infectivity_ceiling: 1 fixtop: - 0.6 - 1 fixbottom: 0 fixslope: - 0.8 - 10
Curve-fitting QC:
curvefit_qc:
max_frac_infectivity_at_least: 0.0
goodness_of_fit:
min_R2: 0.5
max_RMSD: 0.15
serum_replicates_ignore_curvefit_qc: []
barcode_serum_replicates_ignore_curvefit_qc: []
Set up dictionary to keep track of wells, barcodes, well-barcodes, and serum-replicates that are dropped:
qc_drops = {
"wells": {},
"barcodes": {},
"barcode_wells": {},
"barcode_serum_replicates": {},
"serum_replicates": {},
}
assert set(manual_drops).issubset(
qc_drops
), f"{manual_drops.keys()=}, {qc_drops.keys()}"
Statistics on barcode-parsing for each sample¶
Make interactive chart of the "fates" of the sequencing reads parsed for each sample on the plate.
If most sequencing reads are not "valid barcodes", this could potentially indicate some problem in the sequencing or barcode set you are parsing.
Potential fates are:
- valid barcode: barcode that matches a known virus or neutralization standard, we hope most reads are this.
- invalid barcode: a barcode with proper flanking sequences, but does not match a known virus or neutralization standard. If you have a lot of reads of this type, it is probably a good idea to look at the invalid barcode CSVs (in the
./results/barcode_invalid/subdirectory created by the pipeline) to see what these invalid barcodes are. - unparseable barcode: could not parse a barcode from this read as there was not a sequence of the correct length with the appropriate flanking sequence.
- invalid outer flank: if using an outer upstream or downstream region (
upstream2ordownstream2for the illuminabarcodeparser), reads that are otherwise valid except for this outer flank. Typically you would be usingupstream2if you have a plate index embedded in your primer, and reads with this classification correspond to a different index than the one for this plate. - low quality barcode: low-quality or
Nnucleotides in barcode, could indicate problem with sequencing. - failed chastity filter: reads that failed the Illumina chastity filter, if these are reported in the FASTQ (they may not be).
Also, if the number of reads per sample is very uneven, that could indicate that you did not do a good job of balancing the different samples in the Illumina sequencing.
fates = (
pd.concat([pd.read_csv(f).assign(sample=s) for f, s in zip(fate_csvs, samples)])
.merge(samples_df, validate="many_to_one", on="sample")
.assign(
fate_counts=lambda x: x.groupby("fate")["count"].transform("sum"),
sample_well=lambda x: x["sample_noplate"] + " (" + x["well"] + ")",
)
.query("fate_counts > 0")[ # only keep fates with at least one count
["fate", "count", "well", "serum_replicate", "sample_well", "dilution_factor"]
]
)
assert len(fates) == len(fates.drop_duplicates())
serum_replicates = sorted(fates["serum_replicate"].unique())
sample_wells = list(
fates.sort_values(["serum_replicate", "dilution_factor"])["sample_well"]
)
serum_selection = alt.selection_point(
fields=["serum_replicate"],
bind=alt.binding_select(
options=[None] + serum_replicates,
labels=["all"] + serum_replicates,
name="serum",
),
)
fates_chart = (
alt.Chart(fates)
.add_params(serum_selection)
.transform_filter(serum_selection)
.encode(
alt.X("count", scale=alt.Scale(nice=False, padding=3)),
alt.Y(
"sample_well",
title=None,
sort=sample_wells,
),
alt.Color("fate", sort=sorted(fates["fate"].unique(), reverse=True)),
alt.Order("fate", sort="descending"),
tooltip=fates.columns.tolist(),
)
.mark_bar(height={"band": 0.85})
.properties(
height=alt.Step(10),
width=200,
title=f"Barcode parsing for {plate}",
)
.configure_axis(grid=False)
)
fates_chart
Read barcode counts and apply manually specified drops¶
Read the counts per barcode:
# get barcode counts
counts = (
pd.concat([pd.read_csv(c).assign(sample=s) for c, s in zip(count_csvs, samples)])
.merge(samples_df, validate="many_to_one", on="sample")
.drop(columns=["replicate", "plate", "fastq"])
.assign(sample_well=lambda x: x["sample_noplate"] + " (" + x["well"] + ")")
)
# classify barcodes as viral or neut standard
barcode_class = pd.concat(
[
pd.read_csv(viral_library_csv)[["barcode", "strain"]].assign(
neut_standard=False,
),
pd.read_csv(neut_standard_set_csv)[["barcode"]].assign(
neut_standard=True,
strain=pd.NA,
),
],
ignore_index=True,
)
# merge counts and classification of barcodes
assert set(counts["barcode"]) == set(barcode_class["barcode"])
counts = counts.merge(barcode_class, on="barcode", validate="many_to_one")
assert set(sample_wells) == set(counts["sample_well"])
assert set(serum_replicates) == set(counts["serum_replicate"])
Apply any manually specified data drops:
for filter_type, filter_drops in manual_drops.items():
print(f"\nDropping {len(filter_drops)} {filter_type} specified in manual_drops")
assert filter_type in qc_drops
qc_drops[filter_type].update(
{w: "manual_drop" for w in filter_drops if not isinstance(w, list)}
)
if filter_type == "barcode_wells":
counts = counts[
~counts.assign(
barcode_well=lambda x: x.apply(
lambda r: (r["barcode"], r["well"]), axis=1
)
)["barcode_well"].isin(qc_drops[filter_type])
]
elif filter_type == "barcode_serum_replicates":
counts = counts[
~counts.assign(
barcode_serum_replicate=lambda x: x.apply(
lambda r: (r["barcode"], r["serum_replicate"]), axis=1
)
)["barcode_serum_replicate"].isin(qc_drops[filter_type])
]
elif filter_type == "wells":
counts = counts[~counts["well"].isin(qc_drops[filter_type])]
elif filter_type == "barcodes":
counts = counts[~counts["barcode"].isin(qc_drops[filter_type])]
else:
assert filter_type in set(counts.columns)
counts = counts[~counts[filter_type].isin(qc_drops[filter_type])]
Average counts per barcode in each well¶
Plot average counts per barcode. If a sample has inadequate barcode counts, it may not have good enough statistics for accurate analysis, and a QC-threshold is applied:
avg_barcode_counts = (
counts.groupby(
["well", "serum_replicate", "sample_well"],
dropna=False,
as_index=False,
)
.aggregate(avg_count=pd.NamedAgg("count", "mean"))
.assign(
fails_qc=lambda x: (
x["avg_count"] < qc_thresholds["avg_barcode_counts_per_well"]
),
)
)
avg_barcode_counts_chart = (
alt.Chart(avg_barcode_counts)
.add_params(serum_selection)
.transform_filter(serum_selection)
.encode(
alt.X(
"avg_count",
title="average barcode counts per well",
scale=alt.Scale(nice=False, padding=3),
),
alt.Y("sample_well", sort=sample_wells),
alt.Color(
"fails_qc",
title=f"fails {qc_thresholds['avg_barcode_counts_per_well']=}",
legend=alt.Legend(titleLimit=500),
),
tooltip=[
alt.Tooltip(c, format=".3g") if avg_barcode_counts[c].dtype == float else c
for c in avg_barcode_counts.columns
],
)
.mark_bar(height={"band": 0.85})
.properties(
height=alt.Step(10),
width=250,
title=f"Average barcode counts per well for {plate}",
)
.configure_axis(grid=False)
)
display(avg_barcode_counts_chart)
# drop wells failing QC
avg_barcode_counts_per_well_drops = list(avg_barcode_counts.query("fails_qc")["well"])
print(
f"\nDropping {len(avg_barcode_counts_per_well_drops)} wells for failing "
f"{qc_thresholds['avg_barcode_counts_per_well']=}: "
+ str(avg_barcode_counts_per_well_drops)
)
qc_drops["wells"].update(
{w: "avg_barcode_counts_per_well" for w in avg_barcode_counts_per_well_drops}
)
counts = counts[~counts["well"].isin(qc_drops["wells"])]
Dropping 2 wells for failing qc_thresholds['avg_barcode_counts_per_well']=500: ['D7', 'H7']
Fraction of counts from neutralization standard¶
Determine the fraction of counts from the neutralization standard in each sample, and make sure this fraction passess the QC threshold.
neut_standard_fracs = (
counts.assign(
neut_standard_count=lambda x: x["count"] * x["neut_standard"].astype(int)
)
.groupby(
["well", "serum_replicate", "sample_well"],
dropna=False,
as_index=False,
)
.aggregate(
total_count=pd.NamedAgg("count", "sum"),
neut_standard_count=pd.NamedAgg("neut_standard_count", "sum"),
)
.assign(
neut_standard_frac=lambda x: x["neut_standard_count"] / x["total_count"],
fails_qc=lambda x: (
x["neut_standard_frac"] < qc_thresholds["min_neut_standard_frac_per_well"]
),
)
)
neut_standard_fracs_chart = (
alt.Chart(neut_standard_fracs)
.add_params(serum_selection)
.transform_filter(serum_selection)
.encode(
alt.X(
"neut_standard_frac",
title="frac counts from neutralization standard per well",
scale=alt.Scale(nice=False, padding=3),
),
alt.Y("sample_well", sort=sample_wells),
alt.Color(
"fails_qc",
title=f"fails {qc_thresholds['min_neut_standard_frac_per_well']=}",
legend=alt.Legend(titleLimit=500),
),
tooltip=[
alt.Tooltip(c, format=".3g") if neut_standard_fracs[c].dtype == float else c
for c in neut_standard_fracs.columns
],
)
.mark_bar(height={"band": 0.85})
.properties(
height=alt.Step(10),
width=250,
title=f"Neutralization-standard fracs per well for {plate}",
)
.configure_axis(grid=False)
.configure_legend(titleLimit=1000)
)
display(neut_standard_fracs_chart)
# drop wells failing QC
min_neut_standard_frac_per_well_drops = list(
neut_standard_fracs.query("fails_qc")["well"]
)
print(
f"\nDropping {len(min_neut_standard_frac_per_well_drops)} wells for failing "
f"{qc_thresholds['min_neut_standard_frac_per_well']=}: "
+ str(min_neut_standard_frac_per_well_drops)
)
qc_drops["wells"].update(
{
w: "min_neut_standard_frac_per_well"
for w in min_neut_standard_frac_per_well_drops
}
)
counts = counts[~counts["well"].isin(qc_drops["wells"])]
Dropping 0 wells for failing qc_thresholds['min_neut_standard_frac_per_well']=0.005: []
Consistency and minimum fractions for barcodes¶
We examine the fraction of counts attributable to each barcode. We do this splitting the data two ways:
Looking at all viral (but not neut-standard) barcodes only for the no-serum samples (wells).
Looking at just the neut-standard barcodes for all samples (wells).
The reasons is that if the experiment is set up perfectly, these fractions should be the same across all samples for each barcode. (We do not expect viral barcodes to have consistent fractions across no-serum samples as they will be neutralized differently depending on strain).
We plot these fractions in interactive plots (you can mouseover points and zoom) so you can identify barcodes that fail the expected consistency QC thresholds.
We also make sure the barcodes meet specified QC minimum thresholds for all samples, and flag any that do not.
barcode_selection = alt.selection_point(fields=["barcode"], on="mouseover", empty=False)
# look at all samples for neut standard barcodes, or no-serum samples for all barcodes
for is_neut_standard, df in counts.groupby("neut_standard"):
if is_neut_standard:
print(
f"\n\n{'=' * 89}\nAnalyzing neut-standard barcodes from all samples (wells)"
)
qc_name = "per_neut_standard_barcode_filters"
else:
print(f"\n\n{'=' * 89}\nAnalyzing all barcodes from no-serum samples (wells)")
qc_name = "no_serum_per_viral_barcode_filters"
df = df.query("serum == 'none'")
df = df.assign(
sample_counts=lambda x: x.groupby("sample")["count"].transform("sum"),
count_frac=lambda x: x["count"] / x["sample_counts"],
median_count_frac=lambda x: x.groupby("barcode")["count_frac"].transform(
"median"
),
fold_change_from_median=lambda x: numpy.where(
x["count_frac"] > x["median_count_frac"],
x["count_frac"] / x["median_count_frac"],
x["median_count_frac"] / x["count_frac"],
),
)[
[
"barcode",
"count",
"well",
"sample_well",
"count_frac",
"median_count_frac",
"fold_change_from_median",
]
+ ([] if is_neut_standard else ["strain"])
]
# barcode fails QC if fails in sufficient wells
qc = qc_thresholds[qc_name]
print(f"Apply QC {qc_name}: {qc}\n")
fails_qc = (
df.assign(
fails_qc=lambda x: ~(
(x["count_frac"] >= qc["min_frac"])
& (x["fold_change_from_median"] <= qc["max_fold_change"])
),
)
.groupby("barcode", as_index=False)
.aggregate(n_wells_fail_qc=pd.NamedAgg("fails_qc", "sum"))
.assign(fails_qc=lambda x: x["n_wells_fail_qc"] >= qc["max_wells"])[
["barcode", "fails_qc"]
]
)
df = df.merge(fails_qc, on="barcode", validate="many_to_one")
# make chart
evenness_chart = (
alt.Chart(df)
.add_params(barcode_selection)
.encode(
alt.X(
"count_frac",
title=(
"barcode's fraction of neut standard counts"
if is_neut_standard
else "barcode's fraction of non-neut standard counts"
),
scale=alt.Scale(nice=False, padding=5),
),
alt.Y("sample_well", sort=sample_wells),
alt.Fill(
"fails_qc",
title=f"fails {qc_name}",
legend=alt.Legend(titleLimit=500),
),
strokeWidth=alt.condition(barcode_selection, alt.value(2), alt.value(0)),
size=alt.condition(barcode_selection, alt.value(60), alt.value(35)),
tooltip=[
alt.Tooltip(c, format=".2g") if df[c].dtype == float else c
for c in df.columns
],
)
.mark_circle(fillOpacity=0.45, stroke="black", strokeOpacity=1)
.properties(
height=alt.Step(10),
width=300,
title=alt.TitleParams(
(
f"{plate} all samples, neut-standard barcodes"
if is_neut_standard
else f"{plate} no-serum samples, all barcodes"
),
subtitle="x-axis is zoomable (use mouse scroll/pan)",
),
)
.configure_axis(grid=False)
.configure_legend(titleLimit=1000)
.interactive()
)
display(evenness_chart)
# drop barcodes failing QC
barcode_drops = list(fails_qc.query("fails_qc")["barcode"])
print(
f"\nDropping {len(barcode_drops)} barcodes for failing {qc=}: {barcode_drops}"
)
qc_drops["barcodes"].update(
{bc: "min_neut_standard_frac_per_well" for bc in barcode_drops}
)
counts = counts[~counts["barcode"].isin(qc_drops["barcodes"])]
=========================================================================================
Analyzing all barcodes from no-serum samples (wells)
Apply QC no_serum_per_viral_barcode_filters: {'min_frac': 0.0001, 'max_fold_change': 4, 'max_wells': 2}
Dropping 34 barcodes for failing qc={'min_frac': 0.0001, 'max_fold_change': 4, 'max_wells': 2}: ['AAAGTAGCAGAGGATT', 'AAATTCACAATATCCA', 'AACAATTAATTTTTCA', 'AAGTTGTACTTAAGGC', 'AATAGGCCCAAATCCA', 'AATTAATGGTAATAAA', 'ACAAAGATAAAAATTT', 'AGAAAAACGACATCAT', 'AGACCATCGCACCCAA', 'AGTGCTATAAAAATCA', 'ATAACGTTTGTGCAAA', 'ATCGATTCGATTGACG', 'ATGCGTCTAAACATAG', 'CAAAAGCAGCACGATA', 'CAAGACAAGCCCTATA', 'CAGATAGTGATGAACA', 'CATAAAAGACTGTATA', 'CCAATCCCAGCCTTTA', 'CCCTCCTCAAGGGTAA', 'CCTATAAGGCCTTACG', 'CGTACGTATGTCCCAG', 'CGTCCCTGGCGTGTCG', 'CGTTAACGGCCTATCC', 'CTCCAATAGGAGACGA', 'GCTGAAGACAGTATTA', 'GTAATTCGCATGCGGA', 'TATATGGAATACTAAA', 'TCGTCCTAGAACCTAA', 'TCTCCGATAGCCCTAC', 'TGGCTAGCGCACACCA', 'TGTTGTAATCTGAATA', 'TTACATTTTTAGAATT', 'TTATGTTTTAATGGTA', 'TTGCTAGTCTACCTGA']
=========================================================================================
Analyzing neut-standard barcodes from all samples (wells)
Apply QC per_neut_standard_barcode_filters: {'min_frac': 0.005, 'max_fold_change': 4, 'max_wells': 2}
Dropping 0 barcodes for failing qc={'min_frac': 0.005, 'max_fold_change': 4, 'max_wells': 2}: []
Compute fraction infectivity¶
The fraction infectivity for viral barcode $v_b$ in sample $s$ is computed as: $$ F_{v_b,s} = \frac{c_{v_b,s} / \left(\sum_{n_b} c_{n_b,s}\right)}{{\rm median}_{s_0}\left[ c_{v_b,s_0} / \left(\sum_{n_b} c_{n_b,s_0}\right)\right]} $$ where
- $c_{v_b,s}$ is the counts of viral barcode $v_b$ in sample $s$.
- $\sum_{n_b} c_{n_b,s}$ is the sum of the counts for all neutralization standard barcodes $n_b$ for sample $s$.
- $c_{v_b,s_0}$ is the counts of viral barcode $v_b$ in no-serum sample $s_0$.
- $\sum_{n_b} c_{n_b,s_0}$ is the sum of the counts for all neutralization standard barcodes $n_b$ for no-serum sample $s_0$.
- ${\rm median}_{s_0}\left[ c_{v_b,s_0} / \left(\sum_{n_b} c_{n_b,s_0}\right)\right]$ is the median taken across all no-serum samples of the counts of viral barcode $v_b$ versus the total counts for all neutralization standard barcodes.
First, compute the total neutralization-standard counts for each sample (well). Plot these, and drop any wells that do not meet the QC threshold.
neut_standard_counts = (
counts.query("neut_standard")
.groupby(
["well", "serum_replicate", "sample_well", "dilution_factor"],
dropna=False,
as_index=False,
)
.aggregate(neut_standard_count=pd.NamedAgg("count", "sum"))
.assign(
fails_qc=lambda x: (
x["neut_standard_count"] < qc_thresholds["min_neut_standard_count_per_well"]
),
)
)
neut_standard_counts_chart = (
alt.Chart(neut_standard_counts)
.add_params(serum_selection)
.transform_filter(serum_selection)
.encode(
alt.X(
"neut_standard_count",
title="counts from neutralization standard",
scale=alt.Scale(nice=False, padding=3),
),
alt.Y("sample_well", sort=sample_wells),
alt.Color(
"fails_qc",
title=f"fails {qc_thresholds['min_neut_standard_count_per_well']=}",
legend=alt.Legend(titleLimit=500),
),
tooltip=[
(
alt.Tooltip(c, format=".3g")
if neut_standard_counts[c].dtype == float
else c
)
for c in neut_standard_counts.columns
],
)
.mark_bar(height={"band": 0.85})
.properties(
height=alt.Step(10),
width=250,
title=f"Neutralization-standard counts for {plate}",
)
.configure_axis(grid=False)
.configure_legend(titleLimit=1000)
)
display(neut_standard_counts_chart)
# drop wells failing QC
min_neut_standard_count_per_well_drops = list(
neut_standard_counts.query("fails_qc")["well"]
)
print(
f"\nDropping {len(min_neut_standard_count_per_well_drops)} wells for failing "
f"{qc_thresholds['min_neut_standard_count_per_well']=}: "
+ str(min_neut_standard_count_per_well_drops)
)
qc_drops["wells"].update(
{
w: "min_neut_standard_count_per_well"
for w in min_neut_standard_count_per_well_drops
}
)
neut_standard_counts = neut_standard_counts[
~neut_standard_counts["well"].isin(qc_drops["wells"])
]
counts = counts[~counts["well"].isin(qc_drops["wells"])]
Dropping 0 wells for failing qc_thresholds['min_neut_standard_count_per_well']=1000: []
Compute and plot the no-serum sample viral barcode counts and check if they pass the QC filters.
no_serum_counts = (
counts.query("serum == 'none'")
.query("not neut_standard")
.merge(neut_standard_counts, validate="many_to_one")[
["barcode", "strain", "well", "sample_well", "count", "neut_standard_count"]
]
.assign(
fails_qc=lambda x: (
x["count"] <= qc_thresholds["min_no_serum_count_per_viral_barcode_well"]
),
)
)
strains = sorted(no_serum_counts["strain"].unique())
strain_selection_dropdown = alt.selection_point(
fields=["strain"],
bind=alt.binding_select(
options=[None] + strains,
labels=["all"] + strains,
name="virus strain",
),
)
# make chart
no_serum_counts_chart = (
alt.Chart(no_serum_counts)
.add_params(barcode_selection, strain_selection_dropdown)
.transform_filter(strain_selection_dropdown)
.encode(
alt.X(
"count", title="viral barcode count", scale=alt.Scale(nice=False, padding=5)
),
alt.Y("sample_well", sort=sample_wells),
alt.Fill(
"fails_qc",
title=f"fails {qc_thresholds['min_no_serum_count_per_viral_barcode_well']=}",
legend=alt.Legend(titleLimit=500),
),
strokeWidth=alt.condition(barcode_selection, alt.value(2), alt.value(0)),
size=alt.condition(barcode_selection, alt.value(60), alt.value(35)),
tooltip=no_serum_counts.columns.tolist(),
)
.mark_circle(fillOpacity=0.6, stroke="black", strokeOpacity=1)
.properties(
height=alt.Step(10),
width=400,
title=f"{plate} viral barcode counts in no-serum samples",
)
.configure_axis(grid=False)
.configure_legend(titleLimit=1000)
.interactive()
)
display(no_serum_counts_chart)
# drop barcode / wells failing QC
min_no_serum_count_per_viral_barcode_well_drops = list(
no_serum_counts.query("fails_qc")[["barcode", "well"]].itertuples(
index=False, name=None
)
)
print(
f"\nDropping {len(min_no_serum_count_per_viral_barcode_well_drops)} barcode-wells for failing "
f"{qc_thresholds['min_no_serum_count_per_viral_barcode_well']=}: "
+ str(min_no_serum_count_per_viral_barcode_well_drops)
)
qc_drops["barcode_wells"].update(
{
w: "min_no_serum_count_per_viral_barcode_well"
for w in min_no_serum_count_per_viral_barcode_well_drops
}
)
no_serum_counts = no_serum_counts[
~no_serum_counts.assign(
barcode_well=lambda x: x.apply(lambda r: (r["barcode"], r["well"]), axis=1)
)["barcode_well"].isin(qc_drops["barcode_wells"])
]
counts = counts[
~counts.assign(
barcode_well=lambda x: x.apply(lambda r: (r["barcode"], r["well"]), axis=1)
)["barcode_well"].isin(qc_drops["barcode_wells"])
]
Dropping 60 barcode-wells for failing qc_thresholds['min_no_serum_count_per_viral_barcode_well']=100: [('AATCCGGTTAACCCCG', 'D12'), ('TTTCATATAATTTGAG', 'D12'), ('AAAACAGGTCCGGTTT', 'D12'), ('GATCTGCTTGGAATGT', 'D12'), ('CCACAAGTTTGAAAAC', 'D12'), ('CGGGAATCTCCCATAC', 'D12'), ('ATTCAATACGTACTTA', 'D12'), ('CATAATGCACAAACGC', 'D12'), ('CCACGCACTTAAATAA', 'D12'), ('CCATCACCTTATACAC', 'D12'), ('CACCGACCAACTCTCT', 'D12'), ('TCCCGAACTGAACGCG', 'D12'), ('TTATAATGGCCGGTAT', 'D12'), ('AACGACACTTACATCC', 'D12'), ('AGACTGTACGCGACAG', 'D12'), ('GAAAGAAAGCTATATG', 'D12'), ('TACTGAGACACTTAAA', 'D12'), ('CGCGAACAACAGGGGA', 'D12'), ('GTTTTTCACTGAGTAG', 'D12'), ('AAAGACCTTTAACTCT', 'D12'), ('AAGCTAATCGTAGTCC', 'D12'), ('AATGACAGCTGTCTAG', 'D12'), ('ACGGACAACCTATCGC', 'D12'), ('CCGGTTTTCGGGACCT', 'D12'), ('CTACTAGAGCAGCGAG', 'D12'), ('CTCATTACAGAAATTG', 'D12'), ('CTTCATCTCATTTAAA', 'D12'), ('GACAGAAACAAAATTA', 'D12'), ('GTAGAAACTAGGAGTT', 'D12'), ('TAGTTGCCCCGACCTG', 'D12'), ('AGTTATGTAAAACGTG', 'H12'), ('AAGTATTGCTACACAT', 'H12'), ('AATCCGATAAGAGCTA', 'H12'), ('CGCAGTACACAACAAG', 'H12'), ('CCCGCTAACCCTGTCT', 'H12'), ('TTAGCTACTAACCCGT', 'H12'), ('ACGTAAATCCCCACAA', 'H12'), ('CACGTTAGTGAGACTT', 'H12'), ('CAGTAGCAAAACATGC', 'H12'), ('ACTATACATAGAAGAA', 'H12'), ('CCGCAATGACAATTTG', 'H12'), ('GACCTCCTGGGCACGC', 'H12'), ('TGCCGATCCAATTGAT', 'H12'), ('ACGCAAATAGACCGAA', 'H12'), ('AGGTGCGAGCCATCAG', 'H12'), ('TCCGCCACTATAACAT', 'H12'), ('CCAGAGACACGCTAGG', 'H12'), ('CACCCAAACGTTCGCA', 'H12'), ('CAATTCGCCGTTCCCC', 'H12'), ('CTACACTACATCAAAT', 'H12'), ('AATTACGCATAGGCCA', 'H12'), ('CCGCTATCATTAACCC', 'H12'), ('CTAAGGGCCTGTTCTT', 'H12'), ('AATGGTCGAGCCATTC', 'H12'), ('ATAGAAAATTATCCGC', 'H12'), ('CAGCCGCTAAAATGAT', 'H12'), ('CCTATTATAGCTAACA', 'H12'), ('CGATCTTTACGAAAAA', 'H12'), ('TAAACTGTAACTTACA', 'H12'), ('TGATCCGCAAGCTTAG', 'H12')]
Compute and plot the median ratio of viral barcode count to neut standard counts across no-serum samples. If library composition is equal, all of these values should be similar:
median_no_serum_ratio = (
no_serum_counts.assign(ratio=lambda x: x["count"] / x["neut_standard_count"])
.groupby(["barcode", "strain"], as_index=False)
.aggregate(median_no_serum_ratio=pd.NamedAgg("ratio", "median"))
)
strain_selection = alt.selection_point(fields=["strain"], on="mouseover", empty=False)
median_no_serum_ratio_chart = (
alt.Chart(median_no_serum_ratio)
.add_params(strain_selection)
.encode(
alt.X(
"median_no_serum_ratio",
title="median ratio of counts",
scale=alt.Scale(nice=False, padding=5),
),
alt.Y(
"barcode",
sort=alt.SortField("median_no_serum_ratio", order="descending"),
axis=alt.Axis(labelFontSize=5),
),
color=alt.condition(strain_selection, alt.value("orange"), alt.value("gray")),
tooltip=[
(
alt.Tooltip(c, format=".3g")
if median_no_serum_ratio[c].dtype == float
else c
)
for c in median_no_serum_ratio.columns
],
)
.mark_bar(height={"band": 0.85})
.properties(
height=alt.Step(5),
width=250,
title=f"{plate} no-serum median ratio viral barcode to neut-standard barcode",
)
.configure_axis(grid=False)
.configure_legend(titleLimit=1000)
)
display(median_no_serum_ratio_chart)
Compute the actual fraction infectivities. We compute both the raw fraction infectivities and the ones with the ceiling applied:
frac_infectivity = (
counts.query("not neut_standard")
.query("serum != 'none'")
.merge(median_no_serum_ratio, validate="many_to_one")
.merge(neut_standard_counts, validate="many_to_one")
.assign(
frac_infectivity_raw=lambda x: (
(x["count"] / x["neut_standard_count"]) / x["median_no_serum_ratio"]
),
frac_infectivity_ceiling=lambda x: x["frac_infectivity_raw"].clip(
upper=curvefit_params["frac_infectivity_ceiling"]
),
concentration=lambda x: 1 / x["dilution_factor"],
plate_barcode=lambda x: x["plate_replicate"] + "-" + x["barcode"],
)[
[
"barcode",
"plate_barcode",
"well",
"strain",
"serum",
"serum_replicate",
"dilution_factor",
"concentration",
"frac_infectivity_raw",
"frac_infectivity_ceiling",
]
]
)
assert len(
frac_infectivity.groupby(["serum", "plate_barcode", "dilution_factor"])
) == len(frac_infectivity)
assert frac_infectivity["dilution_factor"].notnull().all()
assert frac_infectivity["frac_infectivity_raw"].notnull().all()
assert frac_infectivity["frac_infectivity_ceiling"].notnull().all()
Plot the fraction infectivities, both the raw values and with the ceiling applied:
frac_infectivity_chart_df = (
frac_infectivity.assign(
fails_qc=lambda x: (
x["frac_infectivity_raw"]
> qc_thresholds["max_frac_infectivity_per_viral_barcode_well"]
),
)
.melt(
id_vars=[
"barcode",
"strain",
"well",
"serum_replicate",
"dilution_factor",
"fails_qc",
],
value_vars=["frac_infectivity_raw", "frac_infectivity_ceiling"],
var_name="ceiling_applied",
value_name="frac_infectivity",
)
.assign(
ceiling_applied=lambda x: x["ceiling_applied"].map(
{
"frac_infectivity_raw": "raw fraction infectivity",
"frac_infectivity_ceiling": f"fraction infectivity with ceiling at {curvefit_params['frac_infectivity_ceiling']}",
}
)
)
)
frac_infectivity_chart = (
alt.Chart(frac_infectivity_chart_df)
.add_params(strain_selection_dropdown, barcode_selection)
.transform_filter(strain_selection_dropdown)
.encode(
alt.X(
"dilution_factor",
title="dilution factor",
scale=alt.Scale(nice=False, padding=5, type="log"),
),
alt.Y(
"frac_infectivity",
title="fraction infectivity",
scale=alt.Scale(nice=False, padding=5),
),
alt.Column(
"ceiling_applied",
sort="descending",
title=None,
header=alt.Header(labelFontSize=13, labelFontStyle="bold", labelPadding=2),
),
alt.Row(
"serum_replicate",
title=None,
spacing=3,
header=alt.Header(labelFontSize=13, labelFontStyle="bold"),
),
alt.Detail("barcode"),
alt.Shape(
"fails_qc",
title=f"fails {qc_thresholds['max_frac_infectivity_per_viral_barcode_well']=}",
legend=alt.Legend(titleLimit=500, orient="bottom"),
),
color=alt.condition(
barcode_selection, alt.value("black"), alt.value("MediumBlue")
),
strokeWidth=alt.condition(barcode_selection, alt.value(3), alt.value(1)),
opacity=alt.condition(barcode_selection, alt.value(1), alt.value(0.25)),
tooltip=[
(
alt.Tooltip(c, format=".3g")
if frac_infectivity_chart_df[c].dtype == float
else c
)
for c in frac_infectivity_chart_df.columns
],
)
.mark_line(point=True)
.properties(
height=150,
width=250,
title=f"Fraction infectivities for {plate}",
)
.interactive(bind_x=False)
.configure_axis(grid=False)
.configure_legend(titleLimit=1000)
.configure_point(size=50)
.resolve_scale(x="independent", y="independent")
)
display(frac_infectivity_chart)
# drop barcode / wells failing QC
max_frac_infectivity_per_viral_barcode_well_drops = list(
frac_infectivity_chart_df.query("fails_qc")[["barcode", "well"]]
.drop_duplicates()
.itertuples(index=False, name=None)
)
print(
f"\nDropping {len(max_frac_infectivity_per_viral_barcode_well_drops)} barcode-wells for failing "
f"{qc_thresholds['max_frac_infectivity_per_viral_barcode_well']=}: "
+ str(max_frac_infectivity_per_viral_barcode_well_drops)
)
qc_drops["barcode_wells"].update(
{
w: "max_frac_infectivity_per_viral_barcode_well"
for w in max_frac_infectivity_per_viral_barcode_well_drops
}
)
frac_infectivity = frac_infectivity[
~frac_infectivity.assign(
barcode_well=lambda x: x.apply(lambda r: (r["barcode"], r["well"]), axis=1)
)["barcode_well"].isin(qc_drops["barcode_wells"])
]
Dropping 195 barcode-wells for failing qc_thresholds['max_frac_infectivity_per_viral_barcode_well']=3: [('TAGCTGGGCAAAGGCT', 'D2'), ('GACCAAAGCTGCAGGG', 'D2'), ('TAGTTGCCCCGACCTG', 'D2'), ('TAGATAATAAGATTCA', 'D3'), ('GACAGAAACAAAATTA', 'D4'), ('AAATACCCTTGAGATA', 'D4'), ('ATCGTCCCGGACATTT', 'D4'), ('ATGGTTATCTTACCTT', 'D4'), ('TCTTGAATTTCATGGA', 'D4'), ('TATTATCTAAACGGCG', 'D5'), ('GTTTTTCACTGAGTAG', 'D5'), ('ACCCTTTTAGATATGA', 'D5'), ('ACTATACATAGAAGAA', 'D5'), ('GCCCATTGAACGCAGC', 'D5'), ('CTATCTTAATCTACAG', 'D5'), ('TCAAACTATGATATTC', 'D5'), ('ACCGTTTTTCTACCAG', 'D5'), ('CCCGCTAACCCTGTCT', 'D5'), ('CGCCGAACGGCGGCGC', 'D5'), ('ATCGTCCCGGACATTT', 'D5'), ('GAGATAGCCCAGAGGT', 'D6'), ('AACAAGGCCAACATTT', 'D6'), ('CCGCTATCATTAACCC', 'D6'), ('TACCATTTTGGTCCGC', 'D6'), ('CGCAAGGGATACTAAC', 'D6'), ('ATAAAGAATCCCTTGA', 'D6'), ('CCACAAGTTTGAAAAC', 'D6'), ('AAACTTCGTGGTATAC', 'D6'), ('CCATCACCTTATACAC', 'D6'), ('GATTCACGGCCCACAA', 'D6'), ('TGATTCGTCAATTCAT', 'D6'), ('TTTCATATAATTTGAG', 'D6'), ('TCTTGAATTTCATGGA', 'D6'), ('CTACACTACATCAAAT', 'D6'), ('GCAACGAGGTGTAACC', 'D8'), ('AACGACACTTACATCC', 'D8'), ('TTTCATATAATTTGAG', 'D8'), ('AAACTTCGTGGTATAC', 'D8'), ('ACGTAAATCCCCACAA', 'D8'), ('CCACAAGTTTGAAAAC', 'D8'), ('TCAACCCTTCGATGTA', 'D8'), ('GAAGTAACAAACTATG', 'D8'), ('GATTCACGGCCCACAA', 'D8'), ('TTGACTCACCGAATAA', 'D8'), ('CCCATATACTCACAGA', 'D8'), ('CCAATCATGTATCACA', 'D8'), ('AAGCGGTTTAGGTCCA', 'D8'), ('CCACAAGTTTGAAAAC', 'D9'), ('TCTTAACTACCCGATG', 'D9'), ('CCGATAAGACGTCGCT', 'D9'), ('TCTTGAATTTCATGGA', 'D9'), ('TCAACCCTTCGATGTA', 'D9'), ('AGTTATGTAAAACGTG', 'D9'), ('CTATCTTAATCTACAG', 'D9'), ('GCATTATAATCTTGTG', 'D9'), ('ATGGTTATCTTACCTT', 'D9'), ('TGATTCGTCAATTCAT', 'D9'), ('CTACACTACATCAAAT', 'D9'), ('GAAGTAACAAACTATG', 'D9'), ('CTTCATCTCATTTAAA', 'D9'), ('AGTTATGTAAAACGTG', 'D10'), ('CTTGAATACACAAACA', 'D10'), ('AATCTTTCCAATCTTG', 'D10'), ('CCATCACCTTATACAC', 'D10'), ('GGGTGCAATGAATCCA', 'D10'), ('TCTTGAATTTCATGGA', 'D10'), ('GACAGAAACAAAATTA', 'D10'), ('CTTACAAAGGTAATTC', 'D10'), ('TAGATAATAAGATTCA', 'D10'), ('CCGATAAGACGTCGCT', 'D10'), ('AAGCGGTTTAGGTCCA', 'D10'), ('CTATCTTAATCTACAG', 'D10'), ('CGCGAATCACTAAGTA', 'D10'), ('CTGTGAAAAAAAATAC', 'D10'), ('TGATTCGTCAATTCAT', 'D10'), ('CCAATCATGTATCACA', 'D10'), ('TTGACTCACCGAATAA', 'D10'), ('AACGACACTTACATCC', 'D10'), ('GAAAGAAAGCTATATG', 'D10'), ('CATAATGCACAAACGC', 'D10'), ('TTCATCAAGTTGGTGC', 'D11'), ('TCTTGAATTTCATGGA', 'D11'), ('CAAAAAGCTAATAAGT', 'D11'), ('CTTCATCTCATTTAAA', 'D11'), ('CACCACAGTTACTTAA', 'D11'), ('CCGATAAGACGTCGCT', 'D11'), ('CCACGCACTTAAATAA', 'D11'), ('TAGTTGCCCCGACCTG', 'D11'), ('AAATACCCTTGAGATA', 'D11'), ('AGTTATGTAAAACGTG', 'D11'), ('GCATTATAATCTTGTG', 'D11'), ('ATGGTTATCTTACCTT', 'D11'), ('GGCTATATATCTGTTT', 'D11'), ('CGCCGAACGGCGGCGC', 'D11'), ('GATTCACGGCCCACAA', 'D11'), ('CGCAAGGGATACTAAC', 'H2'), ('TGATTCGTCAATTCAT', 'H4'), ('CTTGAATACACAAACA', 'H4'), ('CTATCTTAATCTACAG', 'H4'), ('CACCACAGTTACTTAA', 'H4'), ('GAAAGAAAGCTATATG', 'H4'), ('CTGAAACCTTGTCCTA', 'H5'), ('TACCATTTTGGTCCGC', 'H5'), ('TGAGATCAGCCGGGTG', 'H5'), ('GGTTGCGTAGTTAATC', 'H5'), ('CTTACAAAGGTAATTC', 'H5'), ('CCCGCTAACCCTGTCT', 'H5'), ('CTGTGAAAAAAAATAC', 'H5'), ('GCTAATTCCAAAAGCG', 'H5'), ('TGTAGTATAAGAATAA', 'H5'), ('TCAACCCTTCGATGTA', 'H5'), ('AGTTATGTAAAACGTG', 'H5'), ('ACTATACATAGAAGAA', 'H5'), ('TCTTGAATTTCATGGA', 'H5'), ('TATTATCTAAACGGCG', 'H6'), ('GTTTTTCACTGAGTAG', 'H6'), ('AAGTGGTAGGATAAAA', 'H6'), ('TAGTTGCCCCGACCTG', 'H6'), ('CCACGCACTTAAATAA', 'H8'), ('GCCCATTGAACGCAGC', 'H8'), ('AAACTTCGTGGTATAC', 'H8'), ('AGATCATAAGCAATAA', 'H8'), ('TCTTGAATTTCATGGA', 'H8'), ('TAGATAATAAGATTCA', 'H8'), ('TAAAAGAATGATGGTC', 'H8'), ('CTTACAAAGGTAATTC', 'H8'), ('CACCACAGTTACTTAA', 'H8'), ('GAAGTAACAAACTATG', 'H8'), ('AACAAGGCCAACATTT', 'H8'), ('AAGCGGTTTAGGTCCA', 'H8'), ('TGACAAACACCTGAGG', 'H8'), ('ATAAAGAATCCCTTGA', 'H8'), ('GCTAATTCCAAAAGCG', 'H9'), ('GGGTGCAATGAATCCA', 'H9'), ('CGCGAATCACTAAGTA', 'H9'), ('TCCTTTAACTAATCGA', 'H9'), ('CTTACAAAGGTAATTC', 'H9'), ('TCAACCCTTCGATGTA', 'H9'), ('CAATGGATAATGATAG', 'H9'), ('AAACTTCGTGGTATAC', 'H9'), ('TAGATAATAAGATTCA', 'H9'), ('CCACAAGTTTGAAAAC', 'H9'), ('CACCTTCATCCTAAAG', 'H9'), ('AAATACCCTTGAGATA', 'H9'), ('TTTCATATAATTTGAG', 'H9'), ('TATCAATTCGGTATTA', 'H9'), ('TTAGCTACTAACCCGT', 'H9'), ('TGTAGTATAAGAATAA', 'H9'), ('CGCCGAACGGCGGCGC', 'H9'), ('TCTTGAATTTCATGGA', 'H9'), ('CTACACTACATCAAAT', 'H9'), ('GAAAGAAAGCTATATG', 'H9'), ('AAGTGGTAGGATAAAA', 'H10'), ('TACCATTTTGGTCCGC', 'H10'), ('GCTAATTCCAAAAGCG', 'H10'), ('TTGACTCACCGAATAA', 'H10'), ('CGCAAGGGATACTAAC', 'H10'), ('ACTATACATAGAAGAA', 'H10'), ('CTACACTACATCAAAT', 'H10'), ('TTTATGCCGATAGAGA', 'H10'), ('CAGTAGCAAAACATGC', 'H10'), ('CCACGCACTTAAATAA', 'H10'), ('CGCGAACAACAGGGGA', 'H10'), ('TCAACCCTTCGATGTA', 'H10'), ('AGTTATGTAAAACGTG', 'H10'), ('TAGTTGCCCCGACCTG', 'H10'), ('GTTTTTCACTGAGTAG', 'H10'), ('GCATTATAATCTTGTG', 'H10'), ('CGGCTAAAGTCTATAG', 'H10'), ('TTTCATATAATTTGAG', 'H10'), ('CCCATATACTCACAGA', 'H10'), ('GATTCACGGCCCACAA', 'H10'), ('GCTAATTCCAAAAGCG', 'H11'), ('GCAACGAGGTGTAACC', 'H11'), ('GACCTCCTGGGCACGC', 'H11'), ('CGTATAACTGACGATT', 'H11'), ('TAGTTGCCCCGACCTG', 'H11'), ('CCGCTATCATTAACCC', 'H11'), ('CGTACAGTGTAATCGA', 'H11'), ('GCTTTTGAGAACCATT', 'H11'), ('ATGGTTATCTTACCTT', 'H11'), ('GCCGTAGCGAAATCTT', 'H11'), ('AAAGATAAATTCAAAA', 'H11'), ('GCATTATAATCTTGTG', 'H11'), ('TACTGAGACACTTAAA', 'H11'), ('TAAAAGAATGATGGTC', 'H11'), ('CGCGAATCACTAAGTA', 'H11'), ('ACCGTTTTTCTACCAG', 'H11'), ('GTAGAAACTAGGAGTT', 'H11'), ('CGCGAACAACAGGGGA', 'H11'), ('CCAATCATGTATCACA', 'H11'), ('CATAATGCACAAACGC', 'H11'), ('CCGCAATGACAATTTG', 'H11'), ('TCTTGAATTTCATGGA', 'H11'), ('AAGCGGTTTAGGTCCA', 'H11')]
Check how many dilutions we have per barcode / serum-replicate:
n_dilutions = (
frac_infectivity.groupby(["serum_replicate", "strain", "barcode"], as_index=False)
.aggregate(**{"number of dilutions": pd.NamedAgg("dilution_factor", "nunique")})
.assign(
fails_qc=lambda x: (
x["number of dilutions"]
< qc_thresholds["min_dilutions_per_barcode_serum_replicate"]
),
)
)
n_dilutions_chart = (
alt.Chart(n_dilutions)
.add_params(barcode_selection)
.encode(
alt.X("number of dilutions", scale=alt.Scale(nice=False, padding=4)),
alt.Y("strain", title=None),
alt.Column(
"serum_replicate",
title=None,
header=alt.Header(labelFontSize=12, labelFontStyle="bold", labelPadding=0),
),
alt.Fill(
"fails_qc",
title=f"fails {qc_thresholds['min_dilutions_per_barcode_serum_replicate']=}",
legend=alt.Legend(titleLimit=500, orient="bottom"),
),
strokeWidth=alt.condition(barcode_selection, alt.value(2), alt.value(0)),
size=alt.condition(barcode_selection, alt.value(55), alt.value(35)),
tooltip=[
alt.Tooltip(c, format=".3g") if n_dilutions[c].dtype == float else c
for c in n_dilutions.columns
],
)
.mark_circle(stroke="black", strokeOpacity=1, fillOpacity=0.45)
.properties(
height=alt.Step(10),
width=120,
title=alt.TitleParams(
"number of dilutions for each barcode for each serum-replicate", dy=-2
),
)
)
display(n_dilutions_chart)
# drop barcode / serum-replicates failing QC
min_dilutions_per_barcode_serum_replicate_drops = list(
n_dilutions.query("fails_qc")[["barcode", "serum_replicate"]].itertuples(
index=False, name=None
)
)
print(
f"\nDropping {len(min_dilutions_per_barcode_serum_replicate_drops)} barcode/serum-replicates for failing "
f"{qc_thresholds['min_dilutions_per_barcode_serum_replicate']=}: "
+ str(min_dilutions_per_barcode_serum_replicate_drops)
)
qc_drops["barcode_serum_replicates"].update(
{
w: "min_dilutions_per_barcode_serum_replicate"
for w in min_dilutions_per_barcode_serum_replicate_drops
}
)
frac_infectivity = frac_infectivity[
~frac_infectivity.assign(
barcode_serum_replicate=lambda x: x.apply(
lambda r: (r["barcode"], r["serum_replicate"]), axis=1
)
)["barcode_serum_replicate"].isin(qc_drops["barcode_serum_replicates"])
]
Dropping 1 barcode/serum-replicates for failing qc_thresholds['min_dilutions_per_barcode_serum_replicate']=6: [('TCTTGAATTTCATGGA', 'A230212d0_rd512')]
Fit neutralization curves without applying QC to curves¶
First fit curves to all serum replicates, then we will apply QC on the curve fits. Note that the fitting is done to the fraction infectivities with the ceiling:
fits_noqc = neutcurve.CurveFits(
frac_infectivity.rename(
columns={
"frac_infectivity_ceiling": "fraction infectivity",
"concentration": "serum concentration",
}
),
conc_col="serum concentration",
fracinf_col="fraction infectivity",
virus_col="strain",
serum_col="serum_replicate",
replicate_col="barcode",
fixtop=curvefit_params["fixtop"],
fixbottom=curvefit_params["fixbottom"],
fixslope=curvefit_params["fixslope"],
)
Determine which fits fail the curve fitting QC, and plot them. Note the plot indicates as failing QC any barcode / serum-replicate that fails, even if we are also specified to ignore the QC for that one (so it will not be removed later):
goodness_of_fit = curvefit_qc["goodness_of_fit"]
fit_params_noqc = (
frac_infectivity.groupby(["serum_replicate", "barcode"], as_index=False)
.aggregate(max_frac_infectivity=pd.NamedAgg("frac_infectivity_ceiling", "max"))
.merge(
fits_noqc.fitParams(average_only=False, no_average=True)[
["serum", "virus", "replicate", "r2", "rmsd"]
].rename(columns={"serum": "serum_replicate", "replicate": "barcode"}),
validate="one_to_one",
)
.assign(
fails_max_frac_infectivity_at_least=lambda x: (
x["max_frac_infectivity"] < curvefit_qc["max_frac_infectivity_at_least"]
),
fails_goodness_of_fit=lambda x: (
(x["r2"] < goodness_of_fit["min_R2"])
& (x["rmsd"] > goodness_of_fit["max_RMSD"])
),
fails_qc=lambda x: (
x["fails_max_frac_infectivity_at_least"] | x["fails_goodness_of_fit"]
),
ignore_qc=lambda x: x.apply(
lambda r: (
(
r["serum_replicate"]
in curvefit_qc["serum_replicates_ignore_curvefit_qc"]
)
or (
(r["barcode"], r["serum_replicate"])
in curvefit_qc["barcode_serum_replicates_ignore_curvefit_qc"]
)
),
axis=1,
),
)
)
print(f"Plotting barcode / serum-replicates that fail {curvefit_qc=}\n")
for prop, col in [
("max frac infectivity", "max_frac_infectivity"),
("curve fit R2", "r2"),
("curve fit RMSD", "rmsd"),
]:
fit_params_noqc_chart = (
alt.Chart(fit_params_noqc)
.add_params(barcode_selection)
.encode(
alt.X(col, title=prop, scale=alt.Scale(nice=False, padding=4)),
alt.Y("virus", title=None),
alt.Fill("fails_qc"),
alt.Column(
"serum_replicate",
title=None,
header=alt.Header(
labelFontSize=12, labelFontStyle="bold", labelPadding=0
),
),
strokeWidth=alt.condition(barcode_selection, alt.value(2), alt.value(0)),
size=alt.condition(barcode_selection, alt.value(55), alt.value(35)),
tooltip=[
alt.Tooltip(c, format=".3g") if fit_params_noqc[c].dtype == float else c
for c in fit_params_noqc.columns
],
)
.mark_circle(stroke="black", strokeOpacity=1, fillOpacity=0.55)
.properties(
height=alt.Step(10),
width=120,
title=alt.TitleParams(f"{prop} for each barcode serum-replicate", dy=-2),
)
)
display(fit_params_noqc_chart)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:469: UserWarning: `f` increases with concentration, consider `infectivity_or_neutralized="neutralized" warnings.warn(
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
Plotting barcode / serum-replicates that fail curvefit_qc={'max_frac_infectivity_at_least': 0.0, 'goodness_of_fit': {'min_R2': 0.5, 'max_RMSD': 0.15}, 'serum_replicates_ignore_curvefit_qc': [], 'barcode_serum_replicates_ignore_curvefit_qc': []}
Now get all barcode / serum-replicate pairs that fail any of the QC. Plot curves for just these virus / serum-replicates (we plot all barcodes for a virus even if just one fails QC), and then exclude any that are not specified to ignore the QC:
barcode_serum_replicates_fail_qc = fit_params_noqc.query("fails_qc").reset_index(
drop=True
)
print(f"Here are barcode / serum-replicates that fail {curvefit_qc=}")
display(barcode_serum_replicates_fail_qc)
if len(barcode_serum_replicates_fail_qc):
print("\nCurves for viruses and serum-replicates with at least one failed barcode:")
fig, _ = fits_noqc.plotReplicates(
sera=sorted(barcode_serum_replicates_fail_qc["serum_replicate"].unique()),
viruses=sorted(barcode_serum_replicates_fail_qc["virus"].unique()),
attempt_shared_legend=False,
legendfontsize=8,
titlesize=10,
ticksize=10,
ncol=6,
draw_in_bounds=True,
)
display(fig)
plt.close(fig)
# drop barcode / serum-replicates failing QC
for qc_filter in ["max_frac_infectivity_at_least", "goodness_of_fit"]:
fits_qc_drops = list(
fit_params_noqc.query(f"fails_{qc_filter} and (not ignore_qc)")[
["barcode", "serum_replicate"]
].itertuples(index=False, name=None)
)
print(
f"\nDropping {len(fits_qc_drops)} barcode/serum-replicates for failing "
f"{qc_filter}={curvefit_qc[qc_filter]}: " + str(fits_qc_drops)
)
qc_drops["barcode_serum_replicates"].update({w: qc_filter for w in fits_qc_drops})
frac_infectivity = frac_infectivity[
~frac_infectivity.assign(
barcode_serum_replicate=lambda x: x.apply(
lambda r: (r["barcode"], r["serum_replicate"]), axis=1
)
)["barcode_serum_replicate"].isin(qc_drops["barcode_serum_replicates"])
]
fit_params_noqc = fit_params_noqc[
~fit_params_noqc.assign(
barcode_serum_replicate=lambda x: x.apply(
lambda r: (r["barcode"], r["serum_replicate"]), axis=1
)
)["barcode_serum_replicate"].isin(qc_drops["barcode_serum_replicates"])
]
Here are barcode / serum-replicates that fail curvefit_qc={'max_frac_infectivity_at_least': 0.0, 'goodness_of_fit': {'min_R2': 0.5, 'max_RMSD': 0.15}, 'serum_replicates_ignore_curvefit_qc': [], 'barcode_serum_replicates_ignore_curvefit_qc': []}
| serum_replicate | barcode | max_frac_infectivity | virus | r2 | rmsd | fails_max_frac_infectivity_at_least | fails_goodness_of_fit | fails_qc | ignore_qc | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | A230212d0_rd512 | AAAACAGGTCCGGTTT | 1.000000 | A/SouthAfrica/PET28931/2023 | 0.251701 | 0.303650 | False | True | True | False |
| 1 | A230212d0_rd512 | AAATACCCTTGAGATA | 0.528648 | A/South_Africa/R06506/2023 | 0.142150 | 0.158431 | False | True | True | False |
| 2 | A230212d0_rd512 | AAGTGGTAGGATAAAA | 1.000000 | A/South_Africa/R06506/2023 | -0.101322 | 0.310345 | False | True | True | False |
| 3 | A230212d0_rd512 | AATGACAGCTGTCTAG | 0.852344 | A/Sydney/715/2023 | 0.413007 | 0.228149 | False | True | True | False |
| 4 | A230212d0_rd512 | ACAGTACAGATATGAC | 1.000000 | A/Townsville/68/2023 | 0.478117 | 0.230345 | False | True | True | False |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 137 | A230212d28_rd512 | TTAGCAGTTAACGTAT | 0.788426 | A/YAMAGATA/98/2023 | 0.122278 | 0.270607 | False | True | True | False |
| 138 | A230212d28_rd512 | TTAGTCATCTGGGTGC | 0.782900 | A/SouthSudan/631/2023 | -0.139143 | 0.251537 | False | True | True | False |
| 139 | A230212d28_rd512 | TTATAATGGCCGGTAT | 1.000000 | A/EHIME/50/2023 | -0.086251 | 0.349825 | False | True | True | False |
| 140 | A230212d28_rd512 | TTGCAATTGAAACATA | 1.000000 | A/Cambodia/e0826360/2020 | 0.284349 | 0.279184 | False | True | True | False |
| 141 | A230212d28_rd512 | TTTATGCCGATAGAGA | 1.000000 | A/South_Africa/R05384/2023 | 0.451816 | 0.227628 | False | True | True | False |
142 rows × 10 columns
Curves for viruses and serum-replicates with at least one failed barcode:
Dropping 0 barcode/serum-replicates for failing max_frac_infectivity_at_least=0.0: []
Dropping 142 barcode/serum-replicates for failing goodness_of_fit={'min_R2': 0.5, 'max_RMSD': 0.15}: [('AAAACAGGTCCGGTTT', 'A230212d0_rd512'), ('AAATACCCTTGAGATA', 'A230212d0_rd512'), ('AAGTGGTAGGATAAAA', 'A230212d0_rd512'), ('AATGACAGCTGTCTAG', 'A230212d0_rd512'), ('ACAGTACAGATATGAC', 'A230212d0_rd512'), ('ACCCTTTTAGATATGA', 'A230212d0_rd512'), ('ACGTAAATCCCCACAA', 'A230212d0_rd512'), ('AGATCATAAGCAATAA', 'A230212d0_rd512'), ('AGCAGACACTTTACAT', 'A230212d0_rd512'), ('AGCATGAGCTTGTCAT', 'A230212d0_rd512'), ('AGCTATGCCTAGTGAA', 'A230212d0_rd512'), ('AGGGACTTTATTGTCC', 'A230212d0_rd512'), ('ATAAAGAATCCCTTGA', 'A230212d0_rd512'), ('ATTTATATTGTCGAAC', 'A230212d0_rd512'), ('CAAAAAGCTAATAAGT', 'A230212d0_rd512'), ('CACCCAAACGTTCGCA', 'A230212d0_rd512'), ('CACCTTCATCCTAAAG', 'A230212d0_rd512'), ('CAGTAGCAAAACATGC', 'A230212d0_rd512'), ('CAGTGCCATCCATCCA', 'A230212d0_rd512'), ('CATATTCTAAAATTGA', 'A230212d0_rd512'), ('CATCATTATTACAAAG', 'A230212d0_rd512'), ('CCACAAGTTTGAAAAC', 'A230212d0_rd512'), ('CCACGCACTTAAATAA', 'A230212d0_rd512'), ('CCATATATAAGAAACC', 'A230212d0_rd512'), ('CCCATATACTCACAGA', 'A230212d0_rd512'), ('CCCGCTAACCCTGTCT', 'A230212d0_rd512'), ('CCGATAAGACGTCGCT', 'A230212d0_rd512'), ('CCTATTATAGCTAACA', 'A230212d0_rd512'), ('CGATCTTTACGAAAAA', 'A230212d0_rd512'), ('CGCAAGGGATACTAAC', 'A230212d0_rd512'), ('CGTCAGAAGTTTATAA', 'A230212d0_rd512'), ('CTACACTACATCAAAT', 'A230212d0_rd512'), ('CTACTAGAGCAGCGAG', 'A230212d0_rd512'), ('CTGAAACCTTGTCCTA', 'A230212d0_rd512'), ('CTTACAAAGGTAATTC', 'A230212d0_rd512'), ('CTTGAATACACAAACA', 'A230212d0_rd512'), ('GAAAATCGAGCTTTAA', 'A230212d0_rd512'), ('GAAAGAAAGCTATATG', 'A230212d0_rd512'), ('GACCAAAAAGCAGTAT', 'A230212d0_rd512'), ('GACCAAAGCTGCAGGG', 'A230212d0_rd512'), ('GAGATAGCCCAGAGGT', 'A230212d0_rd512'), ('GCCGTAGCGAAATCTT', 'A230212d0_rd512'), ('GCTTTTGAGAACCATT', 'A230212d0_rd512'), ('GTAGAAACTAGGAGTT', 'A230212d0_rd512'), ('TACCATTTTGGTCCGC', 'A230212d0_rd512'), ('TACTGAGACACTTAAA', 'A230212d0_rd512'), ('TAGATAATAAGATTCA', 'A230212d0_rd512'), ('TATCAATTCGGTATTA', 'A230212d0_rd512'), ('TATCATTTCATCTACA', 'A230212d0_rd512'), ('TCCAAACAGCGTTAAA', 'A230212d0_rd512'), ('TCCGCCACTATAACAT', 'A230212d0_rd512'), ('TCTTAACTACCCGATG', 'A230212d0_rd512'), ('TCTTACATTGAAAGGC', 'A230212d0_rd512'), ('TGATCCGCAAGCTTAG', 'A230212d0_rd512'), ('TGCCGATCCAATTGAT', 'A230212d0_rd512'), ('TTACGACGTCATGTAT', 'A230212d0_rd512'), ('TTACGTCAATGTTTGA', 'A230212d0_rd512'), ('TTAGTCATCTGGGTGC', 'A230212d0_rd512'), ('TTATAATGGCCGGTAT', 'A230212d0_rd512'), ('TTATGATCGAGGTAAA', 'A230212d0_rd512'), ('TTTATGCCGATAGAGA', 'A230212d0_rd512'), ('AAAACAGGTCCGGTTT', 'A230212d28_rd512'), ('AAACTTCGTGGTATAC', 'A230212d28_rd512'), ('AAAGATAAATTCAAAA', 'A230212d28_rd512'), ('AACAAGGCCAACATTT', 'A230212d28_rd512'), ('AACGACAACCATGAAT', 'A230212d28_rd512'), ('AACGACACTTACATCC', 'A230212d28_rd512'), ('AAGAAATTATGGCAGG', 'A230212d28_rd512'), ('AAGCGGTTTAGGTCCA', 'A230212d28_rd512'), ('AAGTGGTAGGATAAAA', 'A230212d28_rd512'), ('AATATACCGGCACTAC', 'A230212d28_rd512'), ('AATCCGATAAGAGCTA', 'A230212d28_rd512'), ('AATCCGGTTAACCCCG', 'A230212d28_rd512'), ('AATCTTTCCAATCTTG', 'A230212d28_rd512'), ('AATGACAGCTGTCTAG', 'A230212d28_rd512'), ('AATGGTCGAGCCATTC', 'A230212d28_rd512'), ('ACAGTACAGATATGAC', 'A230212d28_rd512'), ('ACGGACAACCTATCGC', 'A230212d28_rd512'), ('ACGTAAATCCCCACAA', 'A230212d28_rd512'), ('AGATGGAGGAATAAAC', 'A230212d28_rd512'), ('AGCAGACACTTTACAT', 'A230212d28_rd512'), ('AGCTATGCCTAGTGAA', 'A230212d28_rd512'), ('AGGGACTTTATTGTCC', 'A230212d28_rd512'), ('AGTTATGTAAAACGTG', 'A230212d28_rd512'), ('ATAAAGAATCCCTTGA', 'A230212d28_rd512'), ('ATAATAATCATCAAGA', 'A230212d28_rd512'), ('ATGGTTATCTTACCTT', 'A230212d28_rd512'), ('ATTCAATACGTACTTA', 'A230212d28_rd512'), ('CAAGAAATGTAGTGAA', 'A230212d28_rd512'), ('CAATGGATAATGATAG', 'A230212d28_rd512'), ('CACCACAGTTACTTAA', 'A230212d28_rd512'), ('CACCTTCATCCTAAAG', 'A230212d28_rd512'), ('CAGTAGCAAAACATGC', 'A230212d28_rd512'), ('CATAATGCACAAACGC', 'A230212d28_rd512'), ('CATATTCTAAAATTGA', 'A230212d28_rd512'), ('CATCATTATTACAAAG', 'A230212d28_rd512'), ('CCAATCATGTATCACA', 'A230212d28_rd512'), ('CCACAAGTTTGAAAAC', 'A230212d28_rd512'), ('CCACGTTCATTAGATG', 'A230212d28_rd512'), ('CCAGAGACACGCTAGG', 'A230212d28_rd512'), ('CCATATATAAGAAACC', 'A230212d28_rd512'), ('CCATCACCTTATACAC', 'A230212d28_rd512'), ('CCCATATACTCACAGA', 'A230212d28_rd512'), ('CCCCAGGTATAAAATA', 'A230212d28_rd512'), ('CGATCTTTACGAAAAA', 'A230212d28_rd512'), ('CGCAAGGGATACTAAC', 'A230212d28_rd512'), ('CGCCGAACGGCGGCGC', 'A230212d28_rd512'), ('CGCGAATCACTAAGTA', 'A230212d28_rd512'), ('CTGTGAAAAAAAATAC', 'A230212d28_rd512'), ('GAAAGAAAGCTATATG', 'A230212d28_rd512'), ('GAAGTAACAAACTATG', 'A230212d28_rd512'), ('GACATCAAATAGCAAC', 'A230212d28_rd512'), ('GACCTCCTGGGCACGC', 'A230212d28_rd512'), ('GAGATAGCCCAGAGGT', 'A230212d28_rd512'), ('GAGCCCGAATAGCAAG', 'A230212d28_rd512'), ('GATCTGCTTGGAATGT', 'A230212d28_rd512'), ('GCAACGAGGTGTAACC', 'A230212d28_rd512'), ('GCCCATTGAACGCAGC', 'A230212d28_rd512'), ('GGCAATAAGTTAAATG', 'A230212d28_rd512'), ('GTTATTATGACTTCAT', 'A230212d28_rd512'), ('TAAACTGTAACTTACA', 'A230212d28_rd512'), ('TACCAATGTCATTTGA', 'A230212d28_rd512'), ('TACGAAAATCAAGAGC', 'A230212d28_rd512'), ('TACGACGGAAACAGAA', 'A230212d28_rd512'), ('TAGATAATAAGATTCA', 'A230212d28_rd512'), ('TAGCTGGGCAAAGGCT', 'A230212d28_rd512'), ('TATCATTTCATCTACA', 'A230212d28_rd512'), ('TATCGCAATATGATAA', 'A230212d28_rd512'), ('TATTATCTAAACGGCG', 'A230212d28_rd512'), ('TCAACCCTTCGATGTA', 'A230212d28_rd512'), ('TCCAAACAGCGTTAAA', 'A230212d28_rd512'), ('TCGCGGTAGATTTGCG', 'A230212d28_rd512'), ('TGAATTGCGTGATGGG', 'A230212d28_rd512'), ('TGATCCGCAAGCTTAG', 'A230212d28_rd512'), ('TGATTCGTCAATTCAT', 'A230212d28_rd512'), ('TGTAGTATAAGAATAA', 'A230212d28_rd512'), ('TTACGTCAATGTTTGA', 'A230212d28_rd512'), ('TTAGCAGTTAACGTAT', 'A230212d28_rd512'), ('TTAGTCATCTGGGTGC', 'A230212d28_rd512'), ('TTATAATGGCCGGTAT', 'A230212d28_rd512'), ('TTGCAATTGAAACATA', 'A230212d28_rd512'), ('TTTATGCCGATAGAGA', 'A230212d28_rd512')]
Fit neutralization curves after applying QC¶
No we re-fit curves after applying all the QC:
fits_qc = neutcurve.CurveFits(
frac_infectivity.rename(
columns={
"frac_infectivity_ceiling": "fraction infectivity",
"concentration": "serum concentration",
}
),
conc_col="serum concentration",
fracinf_col="fraction infectivity",
virus_col="strain",
serum_col="serum",
replicate_col="plate_barcode",
fixtop=curvefit_params["fixtop"],
fixbottom=curvefit_params["fixbottom"],
fixslope=curvefit_params["fixslope"],
)
fit_params_qc = fits_qc.fitParams(average_only=False, no_average=True)
assert len(fit_params_qc) <= len(
fits_noqc.fitParams(average_only=False, no_average=True)
)
print(f"Assigning fits for this plate to {group}")
fit_params_qc.insert(0, "group", group)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
/fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s) /fh/fast/bloom_j/computational_notebooks/ckikawa/2024/flu_seqneut_H3N2_2023-2024/.snakemake/conda/3d7bcea0b75814e39f27531956478cb3_/lib/python3.12/site-packages/neutcurve/hillcurve.py:1177: RuntimeWarning: invalid value encountered in power return b + (t - b) / (1 + (c / m) ** s)
Assigning fits for this plate to pilot
Plot all the curves that passed QC:
if fits_qc.sera:
_ = fits_qc.plotReplicates(
attempt_shared_legend=False,
legendfontsize=8,
titlesize=10,
ticksize=10,
ncol=6,
draw_in_bounds=True,
)
else:
print("No sera passed QC.")
Save results to files¶
print(f"Writing fraction infectivities to {frac_infectivity_csv}")
(
frac_infectivity[
[
"serum",
"strain",
"plate_barcode",
"dilution_factor",
"frac_infectivity_raw",
"frac_infectivity_ceiling",
]
]
.sort_values(["serum", "plate_barcode", "dilution_factor"])
.to_csv(frac_infectivity_csv, index=False, float_format="%.4g")
)
print(f"\nWriting fit parameters to {fits_csv}")
(
fit_params_qc.drop(columns=["nreplicates", "ic50_str"]).to_csv(
fits_csv, index=False, float_format="%.4g"
)
)
print(f"\nPickling neutcurve.CurveFits object for these data to {fits_pickle}")
with open(fits_pickle, "wb") as f:
pickle.dump(fits_qc, f)
print(f"\nWriting QC drops to {qc_drops_yaml}")
def tup_to_str(x):
return " ".join(x) if isinstance(x, tuple) else x
qc_drops_for_yaml = {
key: {tup_to_str(key2): val2 for key2, val2 in val.items()}
for key, val in qc_drops.items()
}
with open(qc_drops_yaml, "w") as f:
yaml.YAML(typ="rt").dump(qc_drops_for_yaml, f)
print("\nHere are the QC drops:\n***************************")
yaml.YAML(typ="rt").dump(qc_drops_for_yaml, sys.stdout)
Writing fraction infectivities to results/plates/plate7/frac_infectivity.csv Writing fit parameters to results/plates/plate7/curvefits.csv Pickling neutcurve.CurveFits object for these data to results/plates/plate7/curvefits.pickle Writing QC drops to results/plates/plate7/qc_drops.yml Here are the QC drops: *************************** wells: D7: avg_barcode_counts_per_well H7: avg_barcode_counts_per_well barcodes: AAAGTAGCAGAGGATT: min_neut_standard_frac_per_well AAATTCACAATATCCA: min_neut_standard_frac_per_well AACAATTAATTTTTCA: min_neut_standard_frac_per_well AAGTTGTACTTAAGGC: min_neut_standard_frac_per_well AATAGGCCCAAATCCA: min_neut_standard_frac_per_well AATTAATGGTAATAAA: min_neut_standard_frac_per_well ACAAAGATAAAAATTT: min_neut_standard_frac_per_well AGAAAAACGACATCAT: min_neut_standard_frac_per_well AGACCATCGCACCCAA: min_neut_standard_frac_per_well AGTGCTATAAAAATCA: min_neut_standard_frac_per_well ATAACGTTTGTGCAAA: min_neut_standard_frac_per_well ATCGATTCGATTGACG: min_neut_standard_frac_per_well ATGCGTCTAAACATAG: min_neut_standard_frac_per_well CAAAAGCAGCACGATA: min_neut_standard_frac_per_well CAAGACAAGCCCTATA: min_neut_standard_frac_per_well CAGATAGTGATGAACA: min_neut_standard_frac_per_well CATAAAAGACTGTATA: min_neut_standard_frac_per_well CCAATCCCAGCCTTTA: min_neut_standard_frac_per_well CCCTCCTCAAGGGTAA: min_neut_standard_frac_per_well CCTATAAGGCCTTACG: min_neut_standard_frac_per_well CGTACGTATGTCCCAG: min_neut_standard_frac_per_well CGTCCCTGGCGTGTCG: min_neut_standard_frac_per_well CGTTAACGGCCTATCC: min_neut_standard_frac_per_well CTCCAATAGGAGACGA: min_neut_standard_frac_per_well GCTGAAGACAGTATTA: min_neut_standard_frac_per_well GTAATTCGCATGCGGA: min_neut_standard_frac_per_well TATATGGAATACTAAA: min_neut_standard_frac_per_well TCGTCCTAGAACCTAA: min_neut_standard_frac_per_well TCTCCGATAGCCCTAC: min_neut_standard_frac_per_well TGGCTAGCGCACACCA: min_neut_standard_frac_per_well TGTTGTAATCTGAATA: min_neut_standard_frac_per_well TTACATTTTTAGAATT: min_neut_standard_frac_per_well TTATGTTTTAATGGTA: min_neut_standard_frac_per_well TTGCTAGTCTACCTGA: min_neut_standard_frac_per_well barcode_wells: AATCCGGTTAACCCCG D12: min_no_serum_count_per_viral_barcode_well TTTCATATAATTTGAG D12: min_no_serum_count_per_viral_barcode_well AAAACAGGTCCGGTTT D12: min_no_serum_count_per_viral_barcode_well GATCTGCTTGGAATGT D12: min_no_serum_count_per_viral_barcode_well CCACAAGTTTGAAAAC D12: min_no_serum_count_per_viral_barcode_well CGGGAATCTCCCATAC D12: min_no_serum_count_per_viral_barcode_well ATTCAATACGTACTTA D12: min_no_serum_count_per_viral_barcode_well CATAATGCACAAACGC D12: min_no_serum_count_per_viral_barcode_well CCACGCACTTAAATAA D12: min_no_serum_count_per_viral_barcode_well CCATCACCTTATACAC D12: min_no_serum_count_per_viral_barcode_well CACCGACCAACTCTCT D12: min_no_serum_count_per_viral_barcode_well TCCCGAACTGAACGCG D12: min_no_serum_count_per_viral_barcode_well TTATAATGGCCGGTAT D12: min_no_serum_count_per_viral_barcode_well AACGACACTTACATCC D12: min_no_serum_count_per_viral_barcode_well AGACTGTACGCGACAG D12: min_no_serum_count_per_viral_barcode_well GAAAGAAAGCTATATG D12: min_no_serum_count_per_viral_barcode_well TACTGAGACACTTAAA D12: min_no_serum_count_per_viral_barcode_well CGCGAACAACAGGGGA D12: min_no_serum_count_per_viral_barcode_well GTTTTTCACTGAGTAG D12: min_no_serum_count_per_viral_barcode_well AAAGACCTTTAACTCT D12: min_no_serum_count_per_viral_barcode_well AAGCTAATCGTAGTCC D12: min_no_serum_count_per_viral_barcode_well AATGACAGCTGTCTAG D12: min_no_serum_count_per_viral_barcode_well ACGGACAACCTATCGC D12: min_no_serum_count_per_viral_barcode_well CCGGTTTTCGGGACCT D12: min_no_serum_count_per_viral_barcode_well CTACTAGAGCAGCGAG D12: min_no_serum_count_per_viral_barcode_well CTCATTACAGAAATTG D12: min_no_serum_count_per_viral_barcode_well CTTCATCTCATTTAAA D12: min_no_serum_count_per_viral_barcode_well GACAGAAACAAAATTA D12: min_no_serum_count_per_viral_barcode_well GTAGAAACTAGGAGTT D12: min_no_serum_count_per_viral_barcode_well TAGTTGCCCCGACCTG D12: min_no_serum_count_per_viral_barcode_well AGTTATGTAAAACGTG H12: min_no_serum_count_per_viral_barcode_well AAGTATTGCTACACAT H12: min_no_serum_count_per_viral_barcode_well AATCCGATAAGAGCTA H12: min_no_serum_count_per_viral_barcode_well CGCAGTACACAACAAG H12: min_no_serum_count_per_viral_barcode_well CCCGCTAACCCTGTCT H12: min_no_serum_count_per_viral_barcode_well TTAGCTACTAACCCGT H12: min_no_serum_count_per_viral_barcode_well ACGTAAATCCCCACAA H12: min_no_serum_count_per_viral_barcode_well CACGTTAGTGAGACTT H12: min_no_serum_count_per_viral_barcode_well CAGTAGCAAAACATGC H12: min_no_serum_count_per_viral_barcode_well ACTATACATAGAAGAA H12: min_no_serum_count_per_viral_barcode_well CCGCAATGACAATTTG H12: min_no_serum_count_per_viral_barcode_well GACCTCCTGGGCACGC H12: min_no_serum_count_per_viral_barcode_well TGCCGATCCAATTGAT H12: min_no_serum_count_per_viral_barcode_well ACGCAAATAGACCGAA H12: min_no_serum_count_per_viral_barcode_well AGGTGCGAGCCATCAG H12: min_no_serum_count_per_viral_barcode_well TCCGCCACTATAACAT H12: min_no_serum_count_per_viral_barcode_well CCAGAGACACGCTAGG H12: min_no_serum_count_per_viral_barcode_well CACCCAAACGTTCGCA H12: min_no_serum_count_per_viral_barcode_well CAATTCGCCGTTCCCC H12: min_no_serum_count_per_viral_barcode_well CTACACTACATCAAAT H12: min_no_serum_count_per_viral_barcode_well AATTACGCATAGGCCA H12: min_no_serum_count_per_viral_barcode_well CCGCTATCATTAACCC H12: min_no_serum_count_per_viral_barcode_well CTAAGGGCCTGTTCTT H12: min_no_serum_count_per_viral_barcode_well AATGGTCGAGCCATTC H12: min_no_serum_count_per_viral_barcode_well ATAGAAAATTATCCGC H12: min_no_serum_count_per_viral_barcode_well CAGCCGCTAAAATGAT H12: min_no_serum_count_per_viral_barcode_well CCTATTATAGCTAACA H12: min_no_serum_count_per_viral_barcode_well CGATCTTTACGAAAAA H12: min_no_serum_count_per_viral_barcode_well TAAACTGTAACTTACA H12: min_no_serum_count_per_viral_barcode_well TGATCCGCAAGCTTAG H12: min_no_serum_count_per_viral_barcode_well TAGCTGGGCAAAGGCT D2: max_frac_infectivity_per_viral_barcode_well GACCAAAGCTGCAGGG D2: max_frac_infectivity_per_viral_barcode_well TAGTTGCCCCGACCTG D2: max_frac_infectivity_per_viral_barcode_well TAGATAATAAGATTCA D3: max_frac_infectivity_per_viral_barcode_well GACAGAAACAAAATTA D4: max_frac_infectivity_per_viral_barcode_well AAATACCCTTGAGATA D4: max_frac_infectivity_per_viral_barcode_well ATCGTCCCGGACATTT D4: max_frac_infectivity_per_viral_barcode_well ATGGTTATCTTACCTT D4: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA D4: max_frac_infectivity_per_viral_barcode_well TATTATCTAAACGGCG D5: max_frac_infectivity_per_viral_barcode_well GTTTTTCACTGAGTAG D5: max_frac_infectivity_per_viral_barcode_well ACCCTTTTAGATATGA D5: max_frac_infectivity_per_viral_barcode_well ACTATACATAGAAGAA D5: max_frac_infectivity_per_viral_barcode_well GCCCATTGAACGCAGC D5: max_frac_infectivity_per_viral_barcode_well CTATCTTAATCTACAG D5: max_frac_infectivity_per_viral_barcode_well TCAAACTATGATATTC D5: max_frac_infectivity_per_viral_barcode_well ACCGTTTTTCTACCAG D5: max_frac_infectivity_per_viral_barcode_well CCCGCTAACCCTGTCT D5: max_frac_infectivity_per_viral_barcode_well CGCCGAACGGCGGCGC D5: max_frac_infectivity_per_viral_barcode_well ATCGTCCCGGACATTT D5: max_frac_infectivity_per_viral_barcode_well GAGATAGCCCAGAGGT D6: max_frac_infectivity_per_viral_barcode_well AACAAGGCCAACATTT D6: max_frac_infectivity_per_viral_barcode_well CCGCTATCATTAACCC D6: max_frac_infectivity_per_viral_barcode_well TACCATTTTGGTCCGC D6: max_frac_infectivity_per_viral_barcode_well CGCAAGGGATACTAAC D6: max_frac_infectivity_per_viral_barcode_well ATAAAGAATCCCTTGA D6: max_frac_infectivity_per_viral_barcode_well CCACAAGTTTGAAAAC D6: max_frac_infectivity_per_viral_barcode_well AAACTTCGTGGTATAC D6: max_frac_infectivity_per_viral_barcode_well CCATCACCTTATACAC D6: max_frac_infectivity_per_viral_barcode_well GATTCACGGCCCACAA D6: max_frac_infectivity_per_viral_barcode_well TGATTCGTCAATTCAT D6: max_frac_infectivity_per_viral_barcode_well TTTCATATAATTTGAG D6: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA D6: max_frac_infectivity_per_viral_barcode_well CTACACTACATCAAAT D6: max_frac_infectivity_per_viral_barcode_well GCAACGAGGTGTAACC D8: max_frac_infectivity_per_viral_barcode_well AACGACACTTACATCC D8: max_frac_infectivity_per_viral_barcode_well TTTCATATAATTTGAG D8: max_frac_infectivity_per_viral_barcode_well AAACTTCGTGGTATAC D8: max_frac_infectivity_per_viral_barcode_well ACGTAAATCCCCACAA D8: max_frac_infectivity_per_viral_barcode_well CCACAAGTTTGAAAAC D8: max_frac_infectivity_per_viral_barcode_well TCAACCCTTCGATGTA D8: max_frac_infectivity_per_viral_barcode_well GAAGTAACAAACTATG D8: max_frac_infectivity_per_viral_barcode_well GATTCACGGCCCACAA D8: max_frac_infectivity_per_viral_barcode_well TTGACTCACCGAATAA D8: max_frac_infectivity_per_viral_barcode_well CCCATATACTCACAGA D8: max_frac_infectivity_per_viral_barcode_well CCAATCATGTATCACA D8: max_frac_infectivity_per_viral_barcode_well AAGCGGTTTAGGTCCA D8: max_frac_infectivity_per_viral_barcode_well CCACAAGTTTGAAAAC D9: max_frac_infectivity_per_viral_barcode_well TCTTAACTACCCGATG D9: max_frac_infectivity_per_viral_barcode_well CCGATAAGACGTCGCT D9: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA D9: max_frac_infectivity_per_viral_barcode_well TCAACCCTTCGATGTA D9: max_frac_infectivity_per_viral_barcode_well AGTTATGTAAAACGTG D9: max_frac_infectivity_per_viral_barcode_well CTATCTTAATCTACAG D9: max_frac_infectivity_per_viral_barcode_well GCATTATAATCTTGTG D9: max_frac_infectivity_per_viral_barcode_well ATGGTTATCTTACCTT D9: max_frac_infectivity_per_viral_barcode_well TGATTCGTCAATTCAT D9: max_frac_infectivity_per_viral_barcode_well CTACACTACATCAAAT D9: max_frac_infectivity_per_viral_barcode_well GAAGTAACAAACTATG D9: max_frac_infectivity_per_viral_barcode_well CTTCATCTCATTTAAA D9: max_frac_infectivity_per_viral_barcode_well AGTTATGTAAAACGTG D10: max_frac_infectivity_per_viral_barcode_well CTTGAATACACAAACA D10: max_frac_infectivity_per_viral_barcode_well AATCTTTCCAATCTTG D10: max_frac_infectivity_per_viral_barcode_well CCATCACCTTATACAC D10: max_frac_infectivity_per_viral_barcode_well GGGTGCAATGAATCCA D10: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA D10: max_frac_infectivity_per_viral_barcode_well GACAGAAACAAAATTA D10: max_frac_infectivity_per_viral_barcode_well CTTACAAAGGTAATTC D10: max_frac_infectivity_per_viral_barcode_well TAGATAATAAGATTCA D10: max_frac_infectivity_per_viral_barcode_well CCGATAAGACGTCGCT D10: max_frac_infectivity_per_viral_barcode_well AAGCGGTTTAGGTCCA D10: max_frac_infectivity_per_viral_barcode_well CTATCTTAATCTACAG D10: max_frac_infectivity_per_viral_barcode_well CGCGAATCACTAAGTA D10: max_frac_infectivity_per_viral_barcode_well CTGTGAAAAAAAATAC D10: max_frac_infectivity_per_viral_barcode_well TGATTCGTCAATTCAT D10: max_frac_infectivity_per_viral_barcode_well CCAATCATGTATCACA D10: max_frac_infectivity_per_viral_barcode_well TTGACTCACCGAATAA D10: max_frac_infectivity_per_viral_barcode_well AACGACACTTACATCC D10: max_frac_infectivity_per_viral_barcode_well GAAAGAAAGCTATATG D10: max_frac_infectivity_per_viral_barcode_well CATAATGCACAAACGC D10: max_frac_infectivity_per_viral_barcode_well TTCATCAAGTTGGTGC D11: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA D11: max_frac_infectivity_per_viral_barcode_well CAAAAAGCTAATAAGT D11: max_frac_infectivity_per_viral_barcode_well CTTCATCTCATTTAAA D11: max_frac_infectivity_per_viral_barcode_well CACCACAGTTACTTAA D11: max_frac_infectivity_per_viral_barcode_well CCGATAAGACGTCGCT D11: max_frac_infectivity_per_viral_barcode_well CCACGCACTTAAATAA D11: max_frac_infectivity_per_viral_barcode_well TAGTTGCCCCGACCTG D11: max_frac_infectivity_per_viral_barcode_well AAATACCCTTGAGATA D11: max_frac_infectivity_per_viral_barcode_well AGTTATGTAAAACGTG D11: max_frac_infectivity_per_viral_barcode_well GCATTATAATCTTGTG D11: max_frac_infectivity_per_viral_barcode_well ATGGTTATCTTACCTT D11: max_frac_infectivity_per_viral_barcode_well GGCTATATATCTGTTT D11: max_frac_infectivity_per_viral_barcode_well CGCCGAACGGCGGCGC D11: max_frac_infectivity_per_viral_barcode_well GATTCACGGCCCACAA D11: max_frac_infectivity_per_viral_barcode_well CGCAAGGGATACTAAC H2: max_frac_infectivity_per_viral_barcode_well TGATTCGTCAATTCAT H4: max_frac_infectivity_per_viral_barcode_well CTTGAATACACAAACA H4: max_frac_infectivity_per_viral_barcode_well CTATCTTAATCTACAG H4: max_frac_infectivity_per_viral_barcode_well CACCACAGTTACTTAA H4: max_frac_infectivity_per_viral_barcode_well GAAAGAAAGCTATATG H4: max_frac_infectivity_per_viral_barcode_well CTGAAACCTTGTCCTA H5: max_frac_infectivity_per_viral_barcode_well TACCATTTTGGTCCGC H5: max_frac_infectivity_per_viral_barcode_well TGAGATCAGCCGGGTG H5: max_frac_infectivity_per_viral_barcode_well GGTTGCGTAGTTAATC H5: max_frac_infectivity_per_viral_barcode_well CTTACAAAGGTAATTC H5: max_frac_infectivity_per_viral_barcode_well CCCGCTAACCCTGTCT H5: max_frac_infectivity_per_viral_barcode_well CTGTGAAAAAAAATAC H5: max_frac_infectivity_per_viral_barcode_well GCTAATTCCAAAAGCG H5: max_frac_infectivity_per_viral_barcode_well TGTAGTATAAGAATAA H5: max_frac_infectivity_per_viral_barcode_well TCAACCCTTCGATGTA H5: max_frac_infectivity_per_viral_barcode_well AGTTATGTAAAACGTG H5: max_frac_infectivity_per_viral_barcode_well ACTATACATAGAAGAA H5: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA H5: max_frac_infectivity_per_viral_barcode_well TATTATCTAAACGGCG H6: max_frac_infectivity_per_viral_barcode_well GTTTTTCACTGAGTAG H6: max_frac_infectivity_per_viral_barcode_well AAGTGGTAGGATAAAA H6: max_frac_infectivity_per_viral_barcode_well TAGTTGCCCCGACCTG H6: max_frac_infectivity_per_viral_barcode_well CCACGCACTTAAATAA H8: max_frac_infectivity_per_viral_barcode_well GCCCATTGAACGCAGC H8: max_frac_infectivity_per_viral_barcode_well AAACTTCGTGGTATAC H8: max_frac_infectivity_per_viral_barcode_well AGATCATAAGCAATAA H8: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA H8: max_frac_infectivity_per_viral_barcode_well TAGATAATAAGATTCA H8: max_frac_infectivity_per_viral_barcode_well TAAAAGAATGATGGTC H8: max_frac_infectivity_per_viral_barcode_well CTTACAAAGGTAATTC H8: max_frac_infectivity_per_viral_barcode_well CACCACAGTTACTTAA H8: max_frac_infectivity_per_viral_barcode_well GAAGTAACAAACTATG H8: max_frac_infectivity_per_viral_barcode_well AACAAGGCCAACATTT H8: max_frac_infectivity_per_viral_barcode_well AAGCGGTTTAGGTCCA H8: max_frac_infectivity_per_viral_barcode_well TGACAAACACCTGAGG H8: max_frac_infectivity_per_viral_barcode_well ATAAAGAATCCCTTGA H8: max_frac_infectivity_per_viral_barcode_well GCTAATTCCAAAAGCG H9: max_frac_infectivity_per_viral_barcode_well GGGTGCAATGAATCCA H9: max_frac_infectivity_per_viral_barcode_well CGCGAATCACTAAGTA H9: max_frac_infectivity_per_viral_barcode_well TCCTTTAACTAATCGA H9: max_frac_infectivity_per_viral_barcode_well CTTACAAAGGTAATTC H9: max_frac_infectivity_per_viral_barcode_well TCAACCCTTCGATGTA H9: max_frac_infectivity_per_viral_barcode_well CAATGGATAATGATAG H9: max_frac_infectivity_per_viral_barcode_well AAACTTCGTGGTATAC H9: max_frac_infectivity_per_viral_barcode_well TAGATAATAAGATTCA H9: max_frac_infectivity_per_viral_barcode_well CCACAAGTTTGAAAAC H9: max_frac_infectivity_per_viral_barcode_well CACCTTCATCCTAAAG H9: max_frac_infectivity_per_viral_barcode_well AAATACCCTTGAGATA H9: max_frac_infectivity_per_viral_barcode_well TTTCATATAATTTGAG H9: max_frac_infectivity_per_viral_barcode_well TATCAATTCGGTATTA H9: max_frac_infectivity_per_viral_barcode_well TTAGCTACTAACCCGT H9: max_frac_infectivity_per_viral_barcode_well TGTAGTATAAGAATAA H9: max_frac_infectivity_per_viral_barcode_well CGCCGAACGGCGGCGC H9: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA H9: max_frac_infectivity_per_viral_barcode_well CTACACTACATCAAAT H9: max_frac_infectivity_per_viral_barcode_well GAAAGAAAGCTATATG H9: max_frac_infectivity_per_viral_barcode_well AAGTGGTAGGATAAAA H10: max_frac_infectivity_per_viral_barcode_well TACCATTTTGGTCCGC H10: max_frac_infectivity_per_viral_barcode_well GCTAATTCCAAAAGCG H10: max_frac_infectivity_per_viral_barcode_well TTGACTCACCGAATAA H10: max_frac_infectivity_per_viral_barcode_well CGCAAGGGATACTAAC H10: max_frac_infectivity_per_viral_barcode_well ACTATACATAGAAGAA H10: max_frac_infectivity_per_viral_barcode_well CTACACTACATCAAAT H10: max_frac_infectivity_per_viral_barcode_well TTTATGCCGATAGAGA H10: max_frac_infectivity_per_viral_barcode_well CAGTAGCAAAACATGC H10: max_frac_infectivity_per_viral_barcode_well CCACGCACTTAAATAA H10: max_frac_infectivity_per_viral_barcode_well CGCGAACAACAGGGGA H10: max_frac_infectivity_per_viral_barcode_well TCAACCCTTCGATGTA H10: max_frac_infectivity_per_viral_barcode_well AGTTATGTAAAACGTG H10: max_frac_infectivity_per_viral_barcode_well TAGTTGCCCCGACCTG H10: max_frac_infectivity_per_viral_barcode_well GTTTTTCACTGAGTAG H10: max_frac_infectivity_per_viral_barcode_well GCATTATAATCTTGTG H10: max_frac_infectivity_per_viral_barcode_well CGGCTAAAGTCTATAG H10: max_frac_infectivity_per_viral_barcode_well TTTCATATAATTTGAG H10: max_frac_infectivity_per_viral_barcode_well CCCATATACTCACAGA H10: max_frac_infectivity_per_viral_barcode_well GATTCACGGCCCACAA H10: max_frac_infectivity_per_viral_barcode_well GCTAATTCCAAAAGCG H11: max_frac_infectivity_per_viral_barcode_well GCAACGAGGTGTAACC H11: max_frac_infectivity_per_viral_barcode_well GACCTCCTGGGCACGC H11: max_frac_infectivity_per_viral_barcode_well CGTATAACTGACGATT H11: max_frac_infectivity_per_viral_barcode_well TAGTTGCCCCGACCTG H11: max_frac_infectivity_per_viral_barcode_well CCGCTATCATTAACCC H11: max_frac_infectivity_per_viral_barcode_well CGTACAGTGTAATCGA H11: max_frac_infectivity_per_viral_barcode_well GCTTTTGAGAACCATT H11: max_frac_infectivity_per_viral_barcode_well ATGGTTATCTTACCTT H11: max_frac_infectivity_per_viral_barcode_well GCCGTAGCGAAATCTT H11: max_frac_infectivity_per_viral_barcode_well AAAGATAAATTCAAAA H11: max_frac_infectivity_per_viral_barcode_well GCATTATAATCTTGTG H11: max_frac_infectivity_per_viral_barcode_well TACTGAGACACTTAAA H11: max_frac_infectivity_per_viral_barcode_well TAAAAGAATGATGGTC H11: max_frac_infectivity_per_viral_barcode_well CGCGAATCACTAAGTA H11: max_frac_infectivity_per_viral_barcode_well ACCGTTTTTCTACCAG H11: max_frac_infectivity_per_viral_barcode_well GTAGAAACTAGGAGTT H11: max_frac_infectivity_per_viral_barcode_well CGCGAACAACAGGGGA H11: max_frac_infectivity_per_viral_barcode_well CCAATCATGTATCACA H11: max_frac_infectivity_per_viral_barcode_well CATAATGCACAAACGC H11: max_frac_infectivity_per_viral_barcode_well CCGCAATGACAATTTG H11: max_frac_infectivity_per_viral_barcode_well TCTTGAATTTCATGGA H11: max_frac_infectivity_per_viral_barcode_well AAGCGGTTTAGGTCCA H11: max_frac_infectivity_per_viral_barcode_well barcode_serum_replicates: TCTTGAATTTCATGGA A230212d0_rd512: min_dilutions_per_barcode_serum_replicate AAAACAGGTCCGGTTT A230212d0_rd512: goodness_of_fit AAATACCCTTGAGATA A230212d0_rd512: goodness_of_fit AAGTGGTAGGATAAAA A230212d0_rd512: goodness_of_fit AATGACAGCTGTCTAG A230212d0_rd512: goodness_of_fit ACAGTACAGATATGAC A230212d0_rd512: goodness_of_fit ACCCTTTTAGATATGA A230212d0_rd512: goodness_of_fit ACGTAAATCCCCACAA A230212d0_rd512: goodness_of_fit AGATCATAAGCAATAA A230212d0_rd512: goodness_of_fit AGCAGACACTTTACAT A230212d0_rd512: goodness_of_fit AGCATGAGCTTGTCAT A230212d0_rd512: goodness_of_fit AGCTATGCCTAGTGAA A230212d0_rd512: goodness_of_fit AGGGACTTTATTGTCC A230212d0_rd512: goodness_of_fit ATAAAGAATCCCTTGA A230212d0_rd512: goodness_of_fit ATTTATATTGTCGAAC A230212d0_rd512: goodness_of_fit CAAAAAGCTAATAAGT A230212d0_rd512: goodness_of_fit CACCCAAACGTTCGCA A230212d0_rd512: goodness_of_fit CACCTTCATCCTAAAG A230212d0_rd512: goodness_of_fit CAGTAGCAAAACATGC A230212d0_rd512: goodness_of_fit CAGTGCCATCCATCCA A230212d0_rd512: goodness_of_fit CATATTCTAAAATTGA A230212d0_rd512: goodness_of_fit CATCATTATTACAAAG A230212d0_rd512: goodness_of_fit CCACAAGTTTGAAAAC A230212d0_rd512: goodness_of_fit CCACGCACTTAAATAA A230212d0_rd512: goodness_of_fit CCATATATAAGAAACC A230212d0_rd512: goodness_of_fit CCCATATACTCACAGA A230212d0_rd512: goodness_of_fit CCCGCTAACCCTGTCT A230212d0_rd512: goodness_of_fit CCGATAAGACGTCGCT A230212d0_rd512: goodness_of_fit CCTATTATAGCTAACA A230212d0_rd512: goodness_of_fit CGATCTTTACGAAAAA A230212d0_rd512: goodness_of_fit CGCAAGGGATACTAAC A230212d0_rd512: goodness_of_fit CGTCAGAAGTTTATAA A230212d0_rd512: goodness_of_fit CTACACTACATCAAAT A230212d0_rd512: goodness_of_fit CTACTAGAGCAGCGAG A230212d0_rd512: goodness_of_fit CTGAAACCTTGTCCTA A230212d0_rd512: goodness_of_fit CTTACAAAGGTAATTC A230212d0_rd512: goodness_of_fit CTTGAATACACAAACA A230212d0_rd512: goodness_of_fit GAAAATCGAGCTTTAA A230212d0_rd512: goodness_of_fit GAAAGAAAGCTATATG A230212d0_rd512: goodness_of_fit GACCAAAAAGCAGTAT A230212d0_rd512: goodness_of_fit GACCAAAGCTGCAGGG A230212d0_rd512: goodness_of_fit GAGATAGCCCAGAGGT A230212d0_rd512: goodness_of_fit GCCGTAGCGAAATCTT A230212d0_rd512: goodness_of_fit GCTTTTGAGAACCATT A230212d0_rd512: goodness_of_fit GTAGAAACTAGGAGTT A230212d0_rd512: goodness_of_fit TACCATTTTGGTCCGC A230212d0_rd512: goodness_of_fit TACTGAGACACTTAAA A230212d0_rd512: goodness_of_fit TAGATAATAAGATTCA A230212d0_rd512: goodness_of_fit TATCAATTCGGTATTA A230212d0_rd512: goodness_of_fit TATCATTTCATCTACA A230212d0_rd512: goodness_of_fit TCCAAACAGCGTTAAA A230212d0_rd512: goodness_of_fit TCCGCCACTATAACAT A230212d0_rd512: goodness_of_fit TCTTAACTACCCGATG A230212d0_rd512: goodness_of_fit TCTTACATTGAAAGGC A230212d0_rd512: goodness_of_fit TGATCCGCAAGCTTAG A230212d0_rd512: goodness_of_fit TGCCGATCCAATTGAT A230212d0_rd512: goodness_of_fit TTACGACGTCATGTAT A230212d0_rd512: goodness_of_fit TTACGTCAATGTTTGA A230212d0_rd512: goodness_of_fit TTAGTCATCTGGGTGC A230212d0_rd512: goodness_of_fit TTATAATGGCCGGTAT A230212d0_rd512: goodness_of_fit TTATGATCGAGGTAAA A230212d0_rd512: goodness_of_fit TTTATGCCGATAGAGA A230212d0_rd512: goodness_of_fit AAAACAGGTCCGGTTT A230212d28_rd512: goodness_of_fit AAACTTCGTGGTATAC A230212d28_rd512: goodness_of_fit AAAGATAAATTCAAAA A230212d28_rd512: goodness_of_fit AACAAGGCCAACATTT A230212d28_rd512: goodness_of_fit AACGACAACCATGAAT A230212d28_rd512: goodness_of_fit AACGACACTTACATCC A230212d28_rd512: goodness_of_fit AAGAAATTATGGCAGG A230212d28_rd512: goodness_of_fit AAGCGGTTTAGGTCCA A230212d28_rd512: goodness_of_fit AAGTGGTAGGATAAAA A230212d28_rd512: goodness_of_fit AATATACCGGCACTAC A230212d28_rd512: goodness_of_fit AATCCGATAAGAGCTA A230212d28_rd512: goodness_of_fit AATCCGGTTAACCCCG A230212d28_rd512: goodness_of_fit AATCTTTCCAATCTTG A230212d28_rd512: goodness_of_fit AATGACAGCTGTCTAG A230212d28_rd512: goodness_of_fit AATGGTCGAGCCATTC A230212d28_rd512: goodness_of_fit ACAGTACAGATATGAC A230212d28_rd512: goodness_of_fit ACGGACAACCTATCGC A230212d28_rd512: goodness_of_fit ACGTAAATCCCCACAA A230212d28_rd512: goodness_of_fit AGATGGAGGAATAAAC A230212d28_rd512: goodness_of_fit AGCAGACACTTTACAT A230212d28_rd512: goodness_of_fit AGCTATGCCTAGTGAA A230212d28_rd512: goodness_of_fit AGGGACTTTATTGTCC A230212d28_rd512: goodness_of_fit AGTTATGTAAAACGTG A230212d28_rd512: goodness_of_fit ATAAAGAATCCCTTGA A230212d28_rd512: goodness_of_fit ATAATAATCATCAAGA A230212d28_rd512: goodness_of_fit ATGGTTATCTTACCTT A230212d28_rd512: goodness_of_fit ATTCAATACGTACTTA A230212d28_rd512: goodness_of_fit CAAGAAATGTAGTGAA A230212d28_rd512: goodness_of_fit CAATGGATAATGATAG A230212d28_rd512: goodness_of_fit CACCACAGTTACTTAA A230212d28_rd512: goodness_of_fit CACCTTCATCCTAAAG A230212d28_rd512: goodness_of_fit CAGTAGCAAAACATGC A230212d28_rd512: goodness_of_fit CATAATGCACAAACGC A230212d28_rd512: goodness_of_fit CATATTCTAAAATTGA A230212d28_rd512
: goodness_of_fit
CATCATTATTACAAAG A230212d28_rd512: goodness_of_fit
CCAATCATGTATCACA A230212d28_rd512: goodness_of_fit
CCACAAGTTTGAAAAC A230212d28_rd512: goodness_of_fit
CCACGTTCATTAGATG A230212d28_rd512: goodness_of_fit
CCAGAGACACGCTAGG A230212d28_rd512: goodness_of_fit
CCATATATAAGAAACC A230212d28_rd512: goodness_of_fit
CCATCACCTTATACAC A230212d28_rd512: goodness_of_fit
CCCATATACTCACAGA A230212d28_rd512: goodness_of_fit
CCCCAGGTATAAAATA A230212d28_rd512: goodness_of_fit
CGATCTTTACGAAAAA A230212d28_rd512: goodness_of_fit
CGCAAGGGATACTAAC A230212d28_rd512: goodness_of_fit
CGCCGAACGGCGGCGC A230212d28_rd512: goodness_of_fit
CGCGAATCACTAAGTA A230212d28_rd512: goodness_of_fit
CTGTGAAAAAAAATAC A230212d28_rd512: goodness_of_fit
GAAAGAAAGCTATATG A230212d28_rd512: goodness_of_fit
GAAGTAACAAACTATG A230212d28_rd512: goodness_of_fit
GACATCAAATAGCAAC A230212d28_rd512: goodness_of_fit
GACCTCCTGGGCACGC A230212d28_rd512: goodness_of_fit
GAGATAGCCCAGAGGT A230212d28_rd512: goodness_of_fit
GAGCCCGAATAGCAAG A230212d28_rd512: goodness_of_fit
GATCTGCTTGGAATGT A230212d28_rd512: goodness_of_fit
GCAACGAGGTGTAACC A230212d28_rd512: goodness_of_fit
GCCCATTGAACGCAGC A230212d28_rd512: goodness_of_fit
GGCAATAAGTTAAATG A230212d28_rd512: goodness_of_fit
GTTATTATGACTTCAT A230212d28_rd512: goodness_of_fit
TAAACTGTAACTTACA A230212d28_rd512: goodness_of_fit
TACCAATGTCATTTGA A230212d28_rd512: goodness_of_fit
TACGAAAATCAAGAGC A230212d28_rd512: goodness_of_fit
TACGACGGAAACAGAA A230212d28_rd512: goodness_of_fit
TAGATAATAAGATTCA A230212d28_rd512: goodness_of_fit
TAGCTGGGCAAAGGCT A230212d28_rd512: goodness_of_fit
TATCATTTCATCTACA A230212d28_rd512: goodness_of_fit
TATCGCAATATGATAA A230212d28_rd512: goodness_of_fit
TATTATCTAAACGGCG A230212d28_rd512: goodness_of_fit
TCAACCCTTCGATGTA A230212d28_rd512: goodness_of_fit
TCCAAACAGCGTTAAA A230212d28_rd512: goodness_of_fit
TCGCGGTAGATTTGCG A230212d28_rd512: goodness_of_fit
TGAATTGCGTGATGGG A230212d28_rd512: goodness_of_fit
TGATCCGCAAGCTTAG A230212d28_rd512: goodness_of_fit
TGATTCGTCAATTCAT A230212d28_rd512: goodness_of_fit
TGTAGTATAAGAATAA A230212d28_rd512: goodness_of_fit
TTACGTCAATGTTTGA A230212d28_rd512: goodness_of_fit
TTAGCAGTTAACGTAT A230212d28_rd512: goodness_of_fit
TTAGTCATCTGGGTGC A230212d28_rd512: goodness_of_fit
TTATAATGGCCGGTAT A230212d28_rd512: goodness_of_fit
TTGCAATTGAAACATA A230212d28_rd512: goodness_of_fit
TTTATGCCGATAGAGA A230212d28_rd512: goodness_of_fit
serum_replicates: {}